When I run this code in my application :
myProcess terminate. myProcess := nil. myProcess is not set to nil ( but the process is "dead" ). So I played with the SlidingBallDemo and I modify the method stopStepProcess like this : stopStepProcess self isRunning ifTrue: [ Transcript show: 'halt 1'; cr. self stepProcess terminate. Transcript show: 'halt 2'; cr. stepProcess := nil ] If the process is running when the method is executed, then Transcript shows 'halt 1' but not 'halt 2' (the process is dead but stepProcess is not set to nil). If the process is dead when the method is executed, then it shows the two strings (stepProcess is set to nil) . What did I miss ? Thanks Joseph |
Joseph,
> When I run this code in my application : > > myProcess terminate. > myProcess := nil. > > myProcess is not set to nil ( but the process is "dead" ). > > So I played with the SlidingBallDemo and I modify the method > stopStepProcess like this : > > stopStepProcess > self isRunning ifTrue: [ > Transcript show: 'halt 1'; cr. > self stepProcess terminate. > Transcript show: 'halt 2'; cr. > stepProcess := nil ] > > If the process is running when the method is executed, then > Transcript shows 'halt 1' but not 'halt 2' (the process is dead but > stepProcess is not set to nil). > If the process is dead when the method is executed, then it shows the > two strings (stepProcess is set to nil) . > > What did I miss ? Ok, try your example again with the SlidingBallDemo and try double-clicking the window during the slide (this also calls #stopStepProcess). You'll see that this time it works since the doubleclick and the call to #stopStepProcess occur in Dolphin's main user interface process. The reason why it doesn't work when you let the ball slide to the end of its track is that, in this case, it is the step process calling #stopStepProcess to stop *itself*. Hence, after the call to "self stepProcess terminate" the process making that call is now dead so the subsequent statements can never get executed. I suspect something similar is happening in your application. Best regards Andy Bower Dolphin Support www.object-arts.com |
In reply to this post by Joseph Frippiat-2
Joseph Frippiat wrote:
> myProcess terminate. > myProcess := nil. You may find it easier not to use Process>>terminate, but just set a flag that the background Process checks periodically. Not only is that less likely to result in the Process terminating itself, but I think it is also safer in general. I often (well, in-so-far as I use background threads at all ;-) overload the 'myProcess' variable for this purpose. It's a bit hacky, but it does have the advantage that the front-end can start a new backgound process without worrying about existing (obsolete) ones. Code like "in background proc" [myProcess == Pocessor activeProcess] whileTrue: [self oneStepOfBackgroundActivity]. Then the foregound process can either set 'myProc' to nil to stop the backgounder, or start a new backgrounder and assign it to 'myProcess' which will implicitly kill the existing one. -- chris |
In reply to this post by Andy Bower-3
You're right.
I changed the code like this: stopStepProcess self isRunning ifTrue: [ Transcript show: 'halt 1'; cr. [self stepProcess terminate] ensure: [ Transcript show: 'halt 2'; cr. stepProcess := nil ] ] Since it seemed to work, I did the same in my application: [ myProcess terminate ] ensure: [ myProcess := nil. "... other instructions" ] Is there some kind of limitations for what I can put in the block after "ensure:" ? The comment in the method Process>>terminate speaks about the method BlockClosure>>andFinally: but I didn't find it. Thanks Joseph "Andy Bower" <[hidden email]> wrote in message news:[hidden email]... > Joseph, > >> When I run this code in my application : >> >> myProcess terminate. >> myProcess := nil. >> >> myProcess is not set to nil ( but the process is "dead" ). >> >> So I played with the SlidingBallDemo and I modify the method >> stopStepProcess like this : >> >> stopStepProcess >> self isRunning ifTrue: [ >> Transcript show: 'halt 1'; cr. >> self stepProcess terminate. >> Transcript show: 'halt 2'; cr. >> stepProcess := nil ] >> >> If the process is running when the method is executed, then >> Transcript shows 'halt 1' but not 'halt 2' (the process is dead but >> stepProcess is not set to nil). >> If the process is dead when the method is executed, then it shows the >> two strings (stepProcess is set to nil) . >> >> What did I miss ? > > Ok, try your example again with the SlidingBallDemo and try > double-clicking the window during the slide (this also calls > #stopStepProcess). You'll see that this time it works since the > doubleclick and the call to #stopStepProcess occur in Dolphin's main > user interface process. > > The reason why it doesn't work when you let the ball slide to the end > of its track is that, in this case, it is the step process calling > #stopStepProcess to stop *itself*. Hence, after the call to "self > stepProcess terminate" the process making that call is now dead so the > subsequent statements can never get executed. I suspect something > similar is happening in your application. > > Best regards > > Andy Bower > Dolphin Support > www.object-arts.com |
Joseph,
> Since it seemed to work, I did the same in my application: > > [ myProcess terminate ] ensure: [ > myProcess := nil. > "... other instructions" > ] > > Is there some kind of limitations for what I can put in the block after > "ensure:" ? What I tend to do is include the #ensure: block "in the thread". That way, whether the thread exits nromally or otherwise, or another thread terminates it, the cleanup occurs. Note that you might need a Mutex and critical sections (see #critical:) to make it safe. A good starting point would be to have start and stop methods that protect the myProcess instance variable, and to also include a critical section around the cleanup. Re #ensure:, IIRC, the VM restarts the thread long enough to run the ensure block, so it runs on the thread one would expect. A search of the archives will turn up more, and Blair will hopefully jump in to set the record straight as needed. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
"Bill Schwab" <[hidden email]> wrote in message
news:cr1t6v$1212$[hidden email]... > ... > Re #ensure:, IIRC, the VM restarts the thread long enough to run the > ensure block, so it runs on the thread one would expect. A search of the > archives will turn up more, and Blair will hopefully jump in to set the > record straight as needed. Processes are terminated by raising an exception in them. This is true whether the process terminates itself, or is terminated from another process (in the latter case an "interrupt" is sent to the process telling it to raise the terminate exception). This special process termination exception is caught and handled in the a frame at the bottom of the process stack (see BlockClosure>>newProcess). As the stack is unwound back to the exception handler, any #ensure: (and ifCurtailed:) blocks will be run in the normal way. Finally the process is killed off by a primitive, but in fact the primitive does very little except to perform a context switch without putting the process back onto one of the scheduler queues. Assuming there are no other references to the process, it will eventually be garbage collected. Incidentally this does mean you can prevent a process being terminated by catching and ignoring the termination exception, but I wouldn't advise it. Regards Blair |
Free forum by Nabble | Edit this page |