TC calls ContentGetValue after abort

Discuss and announce Total Commander plugins, addons and other useful tools here, both their usage and their development.

Moderators: white, Hacker, petermad, Stefan2

User avatar
aRIEL242
Junior Member
Junior Member
Posts: 64
Joined: 2009-06-29, 12:31 UTC

TC calls ContentGetValue after abort

Post by *aRIEL242 »

This is a question about the development of a content plugin I'm creating.

I have a custom columns set that is composed of 5 calls to ContentGetValue() for a single file.

I've created a trace log and so when switching to that set the sequence call looks like this:
1. ContentGetValue("c:\dir\file.txt", 1, ...);
2. ContentGetValue("c:\dir\file.txt", 2, ...);
3. ContentGetValue("c:\dir\file.txt", 3, ...);
4. ContentGetValue("c:\dir\file.txt", 4, ...);
5. ContentGetValue("c:\dir\file.txt", 5, ...);

When the file is very big the execution of ContentGetValue()is very lengthy for each call.

While the first call to ContentGetValue() is still executing, I abort the operation by switching to a second tab and dues hiding the tab with my columns.

I can see in my trace that Total commander calls ContentStopGetValue() and my code aborts the operation. Then Total commander calls the second ContentGetValue(). Now if I switch to a third tab the second call is being aborted and the third ContentGetValue() is being called. This goes on until all 5 calls are being performed and aborted. And all this is done without returning to the first tab with my custom columns set.

Is this by design?
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48130
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Do you have 5 columns, or a column with 5 values in it?
Author of Total Commander
https://www.ghisler.com
User avatar
aRIEL242
Junior Member
Junior Member
Posts: 64
Joined: 2009-06-29, 12:31 UTC

Post by *aRIEL242 »

ghisler(Author) wrote:Do you have 5 columns, or a column with 5 values in it?
5 columns.

Forgot to mention this in the first post. I'm using TC 8.01 64 bit on win7.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48130
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Custom columns are loaded as a whole only when they are displayed/scrolled into view. Currently it's not possible to abort the loading between two fields, but it should also not be possible to switch tabs while a column is loading, except if the called plugin calls message loop functions (e.g. PeekMessage).
Author of Total Commander
https://www.ghisler.com
User avatar
aRIEL242
Junior Member
Junior Member
Posts: 64
Joined: 2009-06-29, 12:31 UTC

Post by *aRIEL242 »

ghisler(Author) wrote:... but it should also not be possible to switch tabs while a column is loading, except if the called plugin calls message loop functions (e.g. PeekMessage).
:? :? :?
How can that be?
I'm absolutely sure there is no PeekMessage, GetMessage or DispatchMessage hiding in my code.

I just did this:

Code: Select all

int __stdcall ContentGetValueW(WCHAR* FileName, int FieldIndex, int UnitIndex, void* FieldValue, int maxlen, int flags)
{
	if(flags & CONTENT_DELAYIFSLOW)
		return ft_delayed;

	// check field range
	if( (FieldIndex < 0) || (FieldIndex >= fieldcount) )
		return ft_nosuchfield;

	while(true)
	{
		Write2Log(L"ContentGetValue loop my self to death.");
	}

	return ft_fieldempty;
}
My trace file is 719K of this:

Code: Select all

17:33:03> ContentGetValue loop my self to death.
17:33:03> ContentGetValue loop my self to death.
17:33:03> ContentGetValue loop my self to death.
17:33:03> ContentGetValue loop my self to death.
17:33:03> ContentGetValue loop my self to death.
And I have no problem switching tabs.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48130
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Are these calls from the background thread (since you have CONTENT_DELAYIFSLOW in your code)? Or from the foreground thread?
Author of Total Commander
https://www.ghisler.com
User avatar
aRIEL242
Junior Member
Junior Member
Posts: 64
Joined: 2009-06-29, 12:31 UTC

Post by *aRIEL242 »

ghisler(Author) wrote:Are these calls from the background thread (since you have CONTENT_DELAYIFSLOW in your code)? Or from the foreground thread?
Yes. All calls are from the background thread. ft_delayed is returned whenever flags contains CONTENT_DELAYIFSLOW.
User avatar
aRIEL242
Junior Member
Junior Member
Posts: 64
Joined: 2009-06-29, 12:31 UTC

Post by *aRIEL242 »

I've noticed something else.

Assume the entire scenario I described in the first post is being performed on the left panel.
On the right panel are displayed a few vary small files in the default columns set. For small files my ContentGetValue() is immediate.

Back to the scenario in the first post:
After I have switched (on the left panel) from the first tab to the second tab, firing the first ContentStopGetValue(), I change on the right panel to my custom columns set using the same content plugin. The content values on the right will not be displayed and will remained empty until I complete the entire scenario on the left (switching 5 tabs and aborting all 5 ContentGetValue() calls).
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48130
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

The background operations are put in a queue which is handled by one background thread, to avoid that plugin get multiple background calls in parallel.
Author of Total Commander
https://www.ghisler.com
User avatar
aRIEL242
Junior Member
Junior Member
Posts: 64
Joined: 2009-06-29, 12:31 UTC

Post by *aRIEL242 »

ghisler(Author) wrote:The background operations are put in a queue which is handled by one background thread, to avoid that plugin get multiple background calls in parallel.
That makes sense.

But, IMHO, shouldn't all the queued background operations associated with the current directory be cancelled (removed from the queue) when a directory change has occurred?

As it is, only the currently executed background operation is aborted (via ContentStopGetValue) and then the next operation is executed even if that operation is retrieving content for a file that is no longer visible in a directory that is not the current one.
meisl
Member
Member
Posts: 171
Joined: 2013-12-17, 15:30 UTC

Post by *meisl »

Any news on that?
aRIEL242 wrote:But, IMHO, shouldn't all the queued background operations associated with the current directory be cancelled (removed from the queue) when a directory change has occurred?
I second that.

There's a current thread atm where ppl are again struggling with the somewhat unclear semantics of ContentStopGetValue, as well as its "sub-optimal" behaviour (ie on TC's side, when and how it's called).
It could (and was) even argued that the behaviour is actually flawed, under circumstances.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48130
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Unfortunately there are some system calls which cannot be cancelled - the hang until they time out, which can be up to a few minutes.
Author of Total Commander
https://www.ghisler.com
meisl
Member
Member
Posts: 171
Joined: 2013-12-17, 15:30 UTC

Post by *meisl »

Please excuse me, I still don't understand the problem.

I'm assuming (wrongly?) that this queue is a structure of your own, which is built when entering a directory, collecting all (or maybe only those in view) of the files/field/unit triples for which ContentGetValue returns FT_DELAYED.
Then those items from the queue are worked on one by one in the background thread.

I do not assume that maintaining this queue is trivial (view [scroll] changes, files are modified, results coming every now and then from the bg thread, etc...).

However, when leaving the directory (tab change, "folder up", other drive) - I'm wondering just what could make it impossible to call ContentStopGetValue for the currently running op (if any) on the background thread and discard the rest of the queue?
How come that system calls can get in your way there?

Most probably I'm imagining things way simpler than they really are.
So obviously I need your help :)
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48130
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

ContentStopGetValue is already called when changing directories, and the list of fields to be extracted is cleared. However, this doesn't help if the function inside the plugin hangs because the file cannot be accessed.
Author of Total Commander
https://www.ghisler.com
meisl
Member
Member
Posts: 171
Joined: 2013-12-17, 15:30 UTC

Post by *meisl »

Sure.

But we're talking of a different problem!
It occurs after the plugin DID react immediately to ContentStopGetValue, by returning FT_FIELDEMPTY from the expensive op on the bg thread.
TC starts re-requesting the expensive fields on files in the already-left directory!
EDIT: it really does, under circumstances. This has lead to the impression that mentioned queue might never be cleared at all which, precisely, might not be the case. However, there *IS* something wrong with TC's behaviour, and it really impacts users' experience.

It has been detailed in various posts, including in this thread.

But maybe we should collect it all again, with whatever necessary detailed instruction on how to reproduce,
in a new bug report?

Best Regards,
meisl
Post Reply