IdentitySet subclass:#SemaphoreSet
instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
category:'Kernel-Processes'
!
!SemaphoreSet class methodsFor:'documentation'!
documentation
"
SemaphoreSet allow waiting until one of several semaphores become available.
"
!
example2
"
|sema1 sema2 semaSet proc|
sema1 := Semaphore new.
sema2 := Semaphore new.
semaSet := SemaphoreSet with:sema1 with:sema2.
proc := [
[
|ret name|
ret := semaSet waitWithTimeout:5.
ret == sema1 ifTrue:[
name := 'sema1'
] ifFalse:[
ret == sema2 ifTrue:[
name := 'sema2'
] ifFalse:[
name := ret printString
]
].
Transcript showCr: name, ' raised'.
ret isNil ifTrue:[
proc terminate
]
] loop
] fork.
(Delay forSeconds:3) wait.
sema1 signal.
(Delay forSeconds:3) wait.
sema2 signal.
"
!
examples
"
|sema1 sema2 semaSet proc|
sema1 := Semaphore new.
sema2 := Semaphore new.
semaSet := SemaphoreSet with:sema1 with:sema2.
proc := [
[
|ret name|
ret := semaSet wait.
ret == sema1 ifTrue:[
name := 'sema1'
] ifFalse:[
ret == sema2 ifTrue:[
name := 'sema2'
]
].
Transcript showCr: name, ' raised'.
ret == sema2 ifTrue:[
proc terminate
]
] loop
] fork.
(Delay forSeconds:3) wait.
sema1 signal.
(Delay forSeconds:3) wait.
sema2 signal.
"
!
history
"Created: 14.12.1995 / 12:23:21 / stefan"
! !
!SemaphoreSet methodsFor:'wait'!
wait
|currentProcess gotSema wasBlocked registeredAllSemas|
currentProcess := Processor activeProcess.
registeredAllSemas := false.
wasBlocked := OperatingSystem blockInterrupts.
[
gotSema := self detect:[:sema|
sema checkAndRegisterProcess:currentProcess
] ifNone:[
registeredAllSemas := true.
currentProcess suspendWithState:#wait.
nil
].
] doWhile:[gotSema isNil].
"
we finaly got at least one of our semaphores.
Now unregister from any semaphore, we are registered on.
"
self detect:[:sema|
(sema == gotSema) ifTrue:[
registeredAllSemas not
] ifFalse:[
sema unregisterProcess:currentProcess.
false
]
] ifNone:[].
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
^ gotSema
"Modified: 15.12.1995 / 23:10:07 / stefan"
!
waitWithTimeout:seconds
"wait for any of the the semaphore, but abort the wait after some time.
Return the first triggered semaphore if any, nil if we return due to a timeout."
|currentProcess gotSema wasBlocked now endTime unblock timeoutOccured registeredAllSemas|
currentProcess := Processor activeProcess.
timeoutOccured := false.
registeredAllSemas := false.
wasBlocked := OperatingSystem blockInterrupts.
seconds notNil ifTrue:[
"
calculate the end-time
"
now := OperatingSystem getMillisecondTime.
endTime := OperatingSystem millisecondTimeAdd:now and:(seconds * 1000).
unblock := [timeoutOccured := true. Processor resume:currentProcess].
Processor addTimedBlock:unblock for:currentProcess atMilliseconds:endTime.
].
[
gotSema := self detect:[:sema|
sema checkAndRegisterProcess:currentProcess
] ifNone:[
registeredAllSemas := true.
currentProcess suspendWithState:#wait.
nil
].
] doWhile:[gotSema isNil and:[timeoutOccured not]].
(timeoutOccured not and:[unblock notNil]) ifTrue:[
Processor removeTimedBlock:unblock.
].
"
we finaly got at least one of our semaphores.
Now unregister from any semaphore, we are registered on.
"
self detect:[:sema|
(sema == gotSema) ifTrue:[
registeredAllSemas not
] ifFalse:[
sema unregisterProcess:currentProcess.
false
]
] ifNone:[].
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
^ gotSema
"Modified: 15.12.1995 / 23:10:54 / stefan"
"Modified: 16.12.1995 / 02:22:53 / cg"
! !
!SemaphoreSet class methodsFor:'documentation'!
version
"
$Header: /cvs/stx/stx/libbasic/SemaphoreSet.st,v 1.3 1995-12-16 01:23:30 cg Exp $
"
! !