Hi all, @Sven, yes of course I forgot the WeakArray to save the hard ref in my previous explanation. 2013/4/23 Igor Stasenko <siguctua@gmail.com>
On 23 April 2013 18:02, Sean P. DeNigris <sean@clipperadams.com> wrote:
Igor Stasenko wrote
but what you expecting? you refer to 'self' multiple times. sure thing it cannot be GC-ed, neither process will die because of plenty of references on stack. Even block closure which you creating for fork will have home context which keeps reference to 'self', e.g. receiver.
I'm expecting magic apparently because I am stupid when it comes to processes ;) I changed all the "self"s to array first, which also didn't work, but then I read your statement about the home context...
Luc's class-side trick seems to work: Timer>>start
| array | array := WeakArray with: self. process := self class createProcessFor: array. "tried passing self here, but it seemed to keep the process around"
of course, because the home context (will be the method below) of closure captures method's arguments, and holding them strongly..
Timer class>>createProcessFor: aWeakArray
[ [ aWeakArray first notNil ] whileTrue: [ | timer | aWeakArray first interval asDelay wait. "We have to check again if the timer was garbage collected during the wait" aWeakArray first ifNotNil: [ aWeakArray first value: aWeakArray first value +
aWeakArray first announcer announce:
(TimerValueChanged to: aWeakArray
first value) ] ] ] fork.
Wow, it would seem that an object using a process internally that is only valid when the object is around is a fairly common use case. I can't believe how complicated this is :/
it is not apparent to me why this is common use case. :)
you can also simply pass a copy of 'self' to process. as long as copy accessing same announcer, your ticker process will work perfectly. then all you would need to do is:
| copy | copy := self copy.
@Igor. It will not work here I think. because you make the shallow copy before initializing the process and the finalize message is then sent to the copy. as Sven proposed, a WeakArray would be good but I never deeply test it. Anyway, I always fight with the finalization mechanism. With Noury we wrote an ActiveObject class some time ago that has an internal process that is stopped and the activeobject is finalized. The only thing is to be **really** carreful when giving the block to the ActiveObject to not introduce references. Here one of the test case that is green: testDoesStopBlockUponFinalizationForLowestPriority |counter startSemaphore finalizationSemaphore process | counter := 0. startSemaphore := Semaphore new. finalizationSemaphore := Semaphore new. activeObject := ActiveObject do: [ startSemaphore signal. [(Delay forMilliseconds: 50) wait]repeat ] ensure: [ counter := 1. finalizationSemaphore signal. ]. activeObject priority: Processor lowestPriority; start. self deny: (startSemaphore waitTimeoutSeconds: 2). process := activeObject process. activeObject := nil. Smalltalk garbageCollect. self deny: (finalizationSemaphore waitTimeoutSeconds: 2). self assert: counter = 1. self assert: process isTerminated Here the whole code: MCHttpRepository location: 'http://car.mines-douai.fr/squeaksource/ReusableBricks' user: '' password: '' Luc
process := self class createProcessFor: copy. WeakRegistry default add: self executor: copy.
and implement:
finalize process terminate. process := nil.
Then createProcessFor: will be simple:
Timer class>>createProcessFor: timer [ [ timer wait. " make Demeter a bit happier" timer tick. "this should increment counter and announce TimerValueChanged, like that we're not make Demeter unhappy" ] whileTrue ] fork.
(actually , to make mr.Demeter completely happy, i would do [ timer waitAndTick ] whileTrue. )
and, tick, will be something like that:
tick process ifNil: [ ^ false ]. self incrementCounter. self announce: (MyGreatAnnouncement with: whatever). ^ true.
cheerz :)
----- Cheers, Sean -- View this message in context: http://forum.world.st/Terminating-a-Process-when-an-object-dies-tp4683036p46... Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
-- Best regards, Igor Stasenko.