gc and synchronization, Weak Array..

Bob Arning arning at charm.net
Tue May 11 03:29:30 UTC 1999


On Tue, 11 May 1999 09:02:53 +0930 "Peter Smet" <peter.smet at flinders.edu.au> wrote: 
>11 May	Peter Smet	Re: gc and synchronization, Weak Array..
>
--yours--
>
>  I probably should have put some more context to the problem. There is in
>effect a two dimensional
> array of WKDicts. The first has the publishers as its keys. Each of its
>values holds a WKDict holding
> as its keys all the subscribers for that particular publisher. The
>subscriber dict links to further structs like
>  events keys, and messages to send. You get the idea....   So I can test
>the publishers
>  dict by - publishers at: thisObject. Then follows a bunch of methods, each
>digging deeper into
>  the data structure, and finally sending a message to the intended
>receiver. While these messages
> are executing the publisher or the subscriber key can dissapear from its
>dictionary.

Well, that is surprising. Let's suppose you have something like

triggerEvent: aSymbol for: aPublisher

	subscribers _ Publishers at: aPublisher ifAbsent: [^self].
	subscribers keysDo: [ :aSubscriber |
		eventData _ subscribers at: aSubscriber.
		eventData do: [ :each | 
			(each isEvent: aSymbol) ifTrue: [
				each sendTo: aSubscriber
			].
		].
	].

For the entire time this method is executing, "aPublisher" is a strong reference to some object and that object should not get finalized. Similarly, within the #keysDo: block, aSubscriber maintains a strong reference, so within their scope, neither should get finalized.

>  The problem may also be that in my threading tests, the WKDicts are
>getting an incoming stream of new  Objects with no strong references, so the
>arrays are continually being resized. Perhaps the problems
>  are due to array resizing during concurrent access.
>

Yes, if you have multiple threads adding or removing (or even adding and accessing), you could have serious problems if the activeProcess were to change in the middle of an update (or if an update were to occur in the middle of an access). 


I'm a little puzzled by "incoming stream of new  Objects with no strong references". How did you create these objects? Your initial reference will be a strong one and as long as some variable on the execution stack is bound to that object, the object should remain alive and well.

>
--yours again--
>
>    I guess then it comes down to, "well, how long do I have?". The problem
>with threads is that you can
>    test for a condition like notNil, but you are not guaranteed that the
>condition will hold while you execute
>    your conditional code (particularly if the conditional code is long,
>complex, or itself has semaphore
>    wait states). Betrand Meyer, the creator of Eiffel, had exactly this
>problem while trying to integrate
>    preCondition clauses with concurrency. Someone may put the gc in a
>higher priority thread, or simply
>    make it more efficient, and suddenly your code no longer works. Dolphin
>Smalltalk even has methods
>    where a weak reference is made temporarily strong (with the "beStrong"
>selector) to avoid the
>    above mentioned problem......
>

I don't think you need anything special here. In the example below, within the block, the variable "k" is bound to the key in question. Unless I'm missing something tricky, this is a strong reference, and so, if "k" is not nil at the beginning of the block, it will remain not nil at least as long as the block exists (and possibly longer given where block temps are stored).

>
>subscriberWKD keysDo: [ :k | k ifNotNil: [k doWhateverWith: (subscriberWKD
>at: k)]].
>

If you want to send me a snippet that exhibits this problem, I'd be happy to look at it.

Cheers,
Bob





More information about the Squeak-dev mailing list