OperationQueue.st
changeset 929 6cd3e1443daa
child 930 f084913b188a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OperationQueue.st	Fri Dec 01 15:53:45 2000 +0100
@@ -0,0 +1,183 @@
+"{ Package: 'stx:libbasic2' }"
+
+SharedQueue subclass:#OperationQueue
+	instanceVariableNames:'queueLock consumerProcess consumerProcessPriority'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Kernel-Processes'
+!
+
+Object subclass:#OperationInQueue
+	instanceVariableNames:'operation operationPerformedSema operationResult'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:OperationQueue
+!
+
+
+!OperationQueue class methodsFor:'instance creation'!
+
+new
+    ^ super new initializeLock
+!
+
+new:n
+    ^ (super new:n) initializeLock
+! !
+
+!OperationQueue methodsFor:'accessing'!
+
+consumerProcess
+    "return the value of the instance variable 'consumerProcess' (automatically generated)"
+
+    ^ consumerProcess
+!
+
+consumerProcessPriority
+    "return the value of the instance variable 'consumerProcessPriority' (automatically generated)"
+
+    ^ consumerProcessPriority
+!
+
+consumerProcessPriority:something
+    "set the value of the instance variable 'consumerProcessPriority' (automatically generated)"
+
+    consumerProcessPriority := something.
+! !
+
+!OperationQueue methodsFor:'consumer'!
+
+fetchNextOperationAndExecute
+    |opInQ theOperation rslt|
+
+    opInQ := super next.
+
+    theOperation := opInQ operation.
+    rslt := theOperation value.
+    opInQ operationResult:rslt.
+
+    opInQ operationPerformedSema signalForAll.
+
+    [
+        super size == 0 ifTrue:[
+            self stopConsumerProcess
+        ]
+    ] valueUninterruptably
+!
+
+startConsumerProcess
+    [
+        consumerProcess isNil ifTrue:[
+            consumerProcessPriority := consumerProcessPriority ? (Processor userSchedulingPriority).
+            consumerProcess := [
+                [true] whileTrue:[
+                    self fetchNextOperationAndExecute.
+                ].
+            ] newProcess.
+            consumerProcess priority:consumerProcessPriority.
+            consumerProcess name:'Op-Q consumer'.
+            consumerProcess resume.
+        ].
+    ] valueUninterruptably
+!
+
+stopConsumerProcess
+    [
+        |p|
+
+        (p := consumerProcess) notNil ifTrue:[
+            consumerProcess := nil.
+            p terminate
+        ].
+    ] valueUninterruptably
+! !
+
+!OperationQueue methodsFor:'initialization'!
+
+initializeLock
+    queueLock := Semaphore forMutualExclusion.
+! !
+
+!OperationQueue methodsFor:'producer'!
+
+scheduleOperation:anotherOperation
+    "add anOperation (something that understands #value) to the op-queue;
+     wait until the operation has performed (#value been sent),
+     return the result of the #value send"
+
+    |myOpInQ|
+
+    queueLock wait.  "/ get exclusive access to my queue
+
+    "/ operation already in queue ?
+
+    myOpInQ := nil.
+    super do:[:eachOpInQ |
+       anotherOperation = eachOpInQ operation ifTrue:[
+            myOpInQ := eachOpInQ
+       ]
+    ].
+
+    myOpInQ isNil ifTrue:[
+        myOpInQ := OperationInQueue new.
+        myOpInQ operationPerformedSema:(Semaphore new).
+        myOpInQ operation:anotherOperation.
+        [
+            super nextPut:myOpInQ.
+            consumerProcess isNil ifTrue:[
+                self startConsumerProcess
+            ].
+        ] valueUninterruptably.
+    ].
+    queueLock signal. "/ give others a chance to access the queue
+
+    "/ wait for my operation
+    myOpInQ operationPerformedSema wait.
+
+    "/ now, the operation has been performed ...
+    ^ myOpInQ operationResult
+! !
+
+!OperationQueue::OperationInQueue methodsFor:'accessing'!
+
+operation
+    "return the value of the instance variable 'operation' (automatically generated)"
+
+    ^ operation
+!
+
+operation:something
+    "set the value of the instance variable 'operation' (automatically generated)"
+
+    operation := something.
+!
+
+operationPerformedSema
+    "return the value of the instance variable 'operationPerformedSema' (automatically generated)"
+
+    ^ operationPerformedSema
+!
+
+operationPerformedSema:something
+    "set the value of the instance variable 'operationPerformedSema' (automatically generated)"
+
+    operationPerformedSema := something.
+!
+
+operationResult
+    "return the value of the instance variable 'operationResult' (automatically generated)"
+
+    ^ operationResult
+!
+
+operationResult:something
+    "set the value of the instance variable 'operationResult' (automatically generated)"
+
+    operationResult := something.
+! !
+
+!OperationQueue class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libbasic2/OperationQueue.st,v 1.1 2000-12-01 14:53:45 martin Exp $'
+! !