--- /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 $'
+! !