Hi all,

@Sven, yes of course I forgot the WeakArray to save the hard ref in my
previous explanation.


2013/4/23 Igor Stasenko <[email protected]>

> On 23 April 2013 18:02, Sean P. DeNigris <[email protected]> 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 +
> 1.
> >                         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-tp4683036p4683144.html
> > Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
> >
>
>
>
> --
> Best regards,
> Igor Stasenko.
>
>

Reply via email to