--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SharedQueue.st Fri Jul 16 11:39:41 1993 +0200
@@ -0,0 +1,126 @@
+"
+ COPYRIGHT (c) 1993 by Claus Gittinger
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+
+Object subclass:#SharedQueue
+ instanceVariableNames:'contentsArray readPosition writePosition
+ tally
+ accessProtect dataAvailable spaceAvailable'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Collections-Ordered'!
+
+SharedQueue comment:'
+SharedQueues provide a safe mechanism for processes to communicate.
+
+See samples in doc/coding.
+
+%W% %E%
+
+'!
+
+!SharedQueue class methodsFor:'instance creation'!
+
+new
+ ^ self new:10
+!
+
+new:size
+ ^ super new init:size
+! !
+
+!SharedQueue methodsFor:'initialization'!
+
+init:size
+ contentsArray := Array new:size.
+ readPosition := writePosition := 1.
+ tally := 0.
+ accessProtect := Semaphore forMutualExclusion.
+ dataAvailable := Semaphore new.
+ spaceAvailable := Semaphore new
+! !
+
+!SharedQueue methodsFor:'accessing'!
+
+next
+ "return the next value in the queue; if it its empty, wait 'til
+ something is put into the receiver.
+ When the datum has been removed, signal space-availability to
+ writers"
+
+ |value ok|
+
+ ok := false.
+ [ok] whileFalse:[
+ [tally == 0] whileTrue:[
+ dataAvailable wait
+ ].
+ accessProtect critical:[
+ "
+ this check is needed, since another process may
+ have read the value in the meantime ...
+ "
+ tally == 0 ifFalse:[
+ value := contentsArray at:readPosition.
+ readPosition := readPosition + 1.
+ readPosition > contentsArray size ifTrue:[
+ readPosition := 1
+ ].
+ tally := tally - 1.
+ tally == (contentsArray size - 1) ifTrue:[
+ spaceAvailable signal
+ ].
+ ok := true
+ ]
+ ]
+ ].
+ ^ value
+!
+
+nextPut:anObject
+ "enter anObject into the queue; wait for available space, if
+ the queue is full. After the put, signal availablity of a datum
+ to readers."
+
+ |value ok|
+
+ ok := false.
+ [ok] whileFalse:[
+ [tally == contentsArray size] whileTrue:[
+ spaceAvailable wait
+ ].
+ accessProtect critical:[
+ tally == contentsArray size ifFalse:[
+ contentsArray at:writePosition put:anObject.
+ writePosition := writePosition + 1.
+ writePosition > contentsArray size ifTrue:[
+ writePosition := 1
+ ].
+ tally := tally + 1.
+ tally == 1 ifTrue:[
+ dataAvailable signal
+ ].
+ ok := true
+ ]
+ ]
+ ].
+ ^ anObject
+! !
+
+!SharedQueue methodsFor:'queries'!
+
+isEmpty
+ ^ tally == 0
+!
+
+size
+ ^ tally
+! !