Multiple processes using #nextPutAll:

"Martin v. Löwis" martin at v.loewis.de
Tue May 29 07:32:43 UTC 2007


>  queue := self newQueue.
>  writingBlock := [queue nextPutAll: (1 to: 10000)].
>  writingBlock
>    fork;
>    fork;
>    fork.
>  Processor yield.
>  self assert: (queue next: 10000) asArray = (1 to: 10000) asArray.
>  self assert: (queue next: 10000) asArray = (1 to: 10000) asArray.
>  self assert: (queue next: 10000) asArray = (1 to: 10000) asArray.
>  self assert: queue atEnd.
> 
> 
> I assume it's because when I fork, the work is done before the
> following fork starts.
> 
> Can somebody help me writing this test?

I assume that nextPutAll: relies on do: to fetch all elements of
the collection. So you could define a BlockingCollection, which
contains a collection, and a semaphore as instance variables.
Then, do: would do

do: aBlock
  collection do:[:each|
     semaphore wait.
     aBlock value: each.
     semaphore signal.
  ].

Alternatively, if it relies on at: also implement

at: index
  | result |
  semaphore wait.
  result := collection at: index.
  semaphore signal.
  ^result.

Then, in the test, you do

sem := Semaphore new.
writingBlock := [queue nextPutAll:
   (BlockingCollection on: (1 to: 10000) with: sem)].
sem signal.

HTH,
Martin




More information about the Squeak-dev mailing list