[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: GWorkspace file operation pause/stop problems
From: |
Wolfgang Lux |
Subject: |
Re: GWorkspace file operation pause/stop problems |
Date: |
Mon, 4 Aug 2014 23:34:28 +0200 |
Hi Riccardo Mottola,
> Wolfgang Lux wrote:
>> I finally got around to upgrade my GNUstep tree and was able to reproduce
>> your problem.
>> Looking at the code, then, the problem is fairly obvious: When you click the
>> pause button for the first time, the paused flag is set to YES and once the
>> FileExecutorObject notices that the flag is set it exits the loop in
>> do{Move,Copy,Link,Remove,Duplicate,Trash}. This also means that the
>> secondary thread that was started to perform the operation in the
>> FileOpExecutor +setPorts: will terminate and the executor object will be
>> released and probably the connection to that object is closed as well. So it
>> looks like the executor attribute in the FileOpInfo class is no longer
>> connected to a valid object that could resume the file operation when you
>> click the pause button again.
> where do you think the thread is "closed"? I suppose when "endOperation" gets
> called.
> I understand it happens in "done" and "dealloc", but that path is taken only
> when the taks ends or stop is hit (in doCopy and doMove... why the other
> differ I'll check later on):
>
> if (([files count] == 0) || stopped)
> {
> [self done];
> }
This code is completely irrelevant regarding the question whether the thread
terminates.
> if stopped or paused are set as flags, the while loop gets a break, but
> "done" is called only on a proper quit/task completion.
>
> Thus I understand that if "pause" is hit, the loop ends, the executor should
> stay around.
> This makes the whole "stop" a bit quirky, but that is different.
>
>
> if what's your understanding of termination instead?
Okay, processing is a bit obfuscated since it involves DO calls between the
threads. I'll try my best to explain what happens when the code is run.
The auxiliary thread is started by calling
[NSThread detachNewThreadSelector: @selector(setPorts:)
toTarget: [FileOpExecutor class]
withObject: ports];
in method FileOpInfo -startOperation. This means that the auxiliary thread will
execute the FileOpExecutor +setPorts: method and finish as soon as that method
returns.
Now turning to the +setPorts: method, it uses DO to call -registerExecutor: on
the FileOpInfo instance on the main thread. So the code in the auxiliary thread
now waits for the -registerExecutor: call on the main thread to finish and once
that happens the auxiliary thread will terminate.
Next looking at the -registerExecutor: method, this uses DO again to call the
-calculateNumFiles method on the FileExecutor instance. This call is going to
be processed on the auxiliary thread while that thread is still waiting for the
-registerExecutor: method to finish on the main thread. Yet, since
-calculateNumFiles is (correctly!) declared as oneway method -registerExecutor:
will not wait for -calculateNumFiles to terminate and just return immediately.
So the main thread sends a reply back to the auxiliary thread which is still
executing the -calculateNumFiles method. But once -calculateNumFiles returns,
the DO call to -registerExecutor: on the auxiliary thread will return as well
and hence the auxiliary thread will terminate.
So finally, we can look at -calculateNumFiles. At the end, this method calls
-performOperation and the latter calls one of the -do... methods, e.g.,
-doMove. So if the loop in -doMove is exited, which happens once the paused
flag is set, the -doMove method, the -performOperation method and the
-calculateNumFiles methods all exit at once. And that means the
-registerExecutor: can return its result and terminate the auxiliary thread.
I hope that description is clear enough.
Wolfgang