gc and synchronization, Weak Array..
peter.smet at flinders.edu.au
Tue May 11 04:38:55 UTC 1999
I've attached a change set with the PostOffice class. I have included
conditionals to make sure the keys will not be nil. All the tests are on the
test4 in particular often breaks, especially if you set timesRepeat: to a
PS Andreas, I changed WeakArray addWeakDependent: to return the newly added
dependent. This seems more consistent with the other collection protocols.
> While these messages
> are executing the publisher or the subscriber key can dissapear from its
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.
Thanks for pointing this out. I should have realised that any parameter
passed to a method
should persist for at least that method's duration!
The other thing that I didnt realise, which Andreas pointed out, is that
no process can interupt
a critical: section. I assumed that only processes waiting for that
particular semaphore couldnt
> 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
>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.
Simply by self torture :-). See the class methods in PostOffice.
500 timesRepeat: [Bag new when: #this send: #that to: 7] or something
similar in a background
process will do the trick...
> 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
>subscriberWKD keysDo: [ :k | k ifNotNil: [k doWhateverWith: (subscriberWKD
If you want to send me a snippet that exhibits this problem, I'd be happy to
look at it.
That would be excellent - just file in the attached change set.
You can run the tests individually, and usually everything is ok.
If you run the PostOffice class start method be prepared for things to
or at least become quite unresponsive.....
Attachment converted: Anon:Publish-Subscribe.11May128pm.cs
More information about the Squeak-dev