SharedQueue.st
changeset 3433 174f21ed6ce8
parent 2032 05ebef21930b
child 3434 78ea8416cc8e
--- a/SharedQueue.st	Mon Oct 20 18:23:54 2014 +0200
+++ b/SharedQueue.st	Tue Oct 21 00:41:09 2014 +0200
@@ -127,11 +127,22 @@
      When the datum has been removed, signal space-availability to
      writers"
 
-    |retVal|
+    |retVal hasLock|
 
-    dataAvailable wait.
-    accessLock critical:[
-        retVal := super next.
+    [
+        hasLock := accessLock wait.
+        [self isEmpty] whileTrue:[
+            accessLock signal.    
+            hasLock := nil.
+            dataAvailable wait.
+            hasLock := accessLock wait.
+        ].
+        retVal := super nextOrNil.
+        hasLock signal.
+    ] ifCurtailed:[
+        hasLock notNil ifTrue:[
+            hasLock signal.
+        ].
     ].
     spaceAvailable signal.
 
@@ -149,9 +160,9 @@
         self isEmpty ifTrue:[
             retVal := exceptionValue value
         ] ifFalse:[
-            retVal := super next.
+            retVal := super nextOrNil.
             anyRemoved := true.
-        ]
+        ].
     ].
     anyRemoved == true ifTrue:[spaceAvailable signal].
 
@@ -174,8 +185,8 @@
     spaceAvailable wait.
     accessLock critical:[
         retVal := super nextPut:anObject.
+        dataAvailable signal.
     ].
-    dataAvailable signal.
     ^ retVal.
 !
 
@@ -185,24 +196,49 @@
     spaceAvailable wait.
     accessLock critical:[
         retVal := super nextPutFirst:anObject.
+        dataAvailable signal.
     ].
-    dataAvailable signal.
     ^ retVal.
 !
 
 nextWithTimeout:seconds
-    "return the next value in the queue; if it its empty, wait 'til
+    "return the next value in the queue; if it its empty, wait until
      something is put into the receiver.
      When the datum has been removed, signal space-availability to
-     writers"
+     writers.
+     Timeout after secondsIn seconds - answer nil if a timeout occurs."
+
+    |retVal hasLock|
 
-    |retVal|
+    [
+        hasLock := accessLock wait.
+        [self isEmpty] whileTrue:[
+            |secondsLeft finishTime|
+
+            accessLock signal.    
+            hasLock := nil.
 
-    (dataAvailable waitWithTimeout:seconds) isNil ifTrue:[
-        ^ nil
-    ].
-    accessLock critical:[
-        retVal := super next.
+            (seconds notNil and:[secondsLeft isNil]) ifTrue:[
+                secondsLeft := seconds.
+                finishTime := Timestamp now + secondsLeft.
+            ].
+            (dataAvailable waitWithTimeout:secondsLeft) isNil ifTrue:[
+                ^ nil.      "timeout"
+            ].
+            finishTime notNil ifTrue:[
+                secondsLeft := finishTime - Timestamp now.
+                secondsLeft <= 0 ifTrue:[
+                    ^ nil.    "timeout"
+                ].
+            ].
+            hasLock := accessLock wait.
+        ].
+        retVal := super nextOrNil.
+        hasLock signal.
+    ] ifCurtailed:[
+        hasLock notNil ifTrue:[
+            hasLock signal.
+        ].
     ].
     spaceAvailable signal.
 
@@ -225,14 +261,14 @@
 
     |count|
 
-    count := 0.
-    [(dataAvailable waitWithTimeout:0) notNil] whileTrue:[
-        count := count + 1.
-    ].    
     accessLock critical:[
+        [
+            count := dataAvailable count.
+            dataAvailable clear.
+        ] valueUninterruptably.
         super removeAll.
     ].
-    count timesRepeat:[spaceAvailable signal].
+    count timesRepeat:[spaceAvailable signal]. 
 !
 
 removeIdentical:anElement ifAbsent:exceptionalValue
@@ -250,7 +286,7 @@
 !
 
 removeLast
-    "return the last value in the queue; if it its empty, wait 'til
+    "return the last value in the queue; if it its empty, wait until
      something is put into the receiver.
      When the datum has been removed, signal space-availability to
      writers"
@@ -286,15 +322,7 @@
 readWaitWithTimeoutMs:ms
     "Return true if a timeout occured (i.e. false, if data is available)."
 
-    |avail|
-
-    dataAvailable wouldBlock ifFalse:[^ false].
-    avail := (dataAvailable waitWithTimeoutMs:ms) notNil.
-    avail ifTrue:[
-        "/ sigh - the above wait has already consumed the sema
-        dataAvailable signal
-    ].
-    ^ avail not
+    ^ (dataAvailable waitUncountedWithTimeoutMs:ms) isNil.
 !
 
 withAccessLockedDo:aBlock
@@ -328,5 +356,6 @@
 !SharedQueue class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/SharedQueue.st,v 1.36 2008-08-08 13:32:03 fm Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/SharedQueue.st,v 1.37 2014-10-20 22:41:09 stefan Exp $'
 ! !
+