SharedQueue.st
changeset 0 1cf8d1747859
child 1 85d662a8509f
--- /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
+! !