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 _______________________________________________ Gnustep-dev mailing list Gnustep-dev@gnu.org https://lists.gnu.org/mailman/listinfo/gnustep-dev