--- a/Semaphore.st Mon Jul 24 16:16:28 2017 +0200
+++ b/Semaphore.st Mon Jul 24 23:06:52 2017 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1993 by Claus Gittinger
All Rights Reserved
@@ -351,7 +349,9 @@
!
waitTimeoutMSecs:milliSeconds
- ^ self waitWithTimeoutMs:milliSeconds
+ ^ self waitWithTimeoutMs:milliSeconds state:#wait
+
+ "Modified: / 24-07-2017 / 21:18:01 / cg"
!
waitTimeoutSeconds:seconds
@@ -482,8 +482,8 @@
|processes anyDead needsReschedule|
processes := waitingProcesses.
-"/ do not set to nil - a waiting process may be suspended and will not be resumed by #makeRunnable: ...
-"/ waitingProcesses := nil.
+ "/ do not set to nil - a waiting process may be suspended and will not be resumed by #makeRunnable: ...
+ "/ waitingProcesses := nil.
needsReschedule := anyDead := false.
processes do:[:eachProcess |
@@ -508,6 +508,7 @@
^ needsReschedule.
"Modified: / 20-02-2017 / 11:34:42 / stefan"
+ "Modified (format): / 24-07-2017 / 18:03:47 / cg"
! !
!Semaphore methodsFor:'private-accessing'!
@@ -914,7 +915,7 @@
"have to wait for Semaphore availability"
timeoutMs ~= 0 ifTrue:[
retVal := [
- gotSema := self waitWithTimeoutMs:timeoutMs.
+ gotSema := self waitWithTimeoutMs:timeoutMs state:#wait.
gotSema notNil ifTrue:[
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
aBlock value.
@@ -947,6 +948,7 @@
"Created: / 18-02-2017 / 22:15:25 / stefan"
"Modified: / 24-07-2017 / 11:43:19 / stefan"
+ "Modified: / 24-07-2017 / 21:17:47 / cg"
!
wait
@@ -991,8 +993,8 @@
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
"Modified: / 13-12-1995 / 13:26:33 / stefan"
- "Modified: / 11-08-2011 / 14:36:43 / cg"
"Modified (format): / 21-02-2017 / 15:29:51 / stefan"
+ "Modified: / 24-07-2017 / 23:04:09 / cg"
!
waitUncounted
@@ -1002,7 +1004,7 @@
|activeProcess wasBlocked|
count > 0 ifTrue:[
- ^ self
+ ^ self
].
activeProcess := Processor activeProcess.
@@ -1014,25 +1016,25 @@
suspend.
"
[count <= 0] whileTrue:[
- self addWaitingProcess:activeProcess.
- "
- for some more descriptive info in processMonitor ...
- ... set the state to #wait (instead of #suspend)
- "
- [
- activeProcess suspendWithState:#wait
- ] ifCurtailed:[
- "interrupts are not blocked when entered through Processor>>#interruptActive"
- OperatingSystem blockInterrupts.
- self removeWaitingProcess:activeProcess.
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ].
- self removeWaitingProcess:activeProcess.
+ self addWaitingProcess:activeProcess.
+ "
+ for some more descriptive info in processMonitor ...
+ ... set the state to #wait (instead of #suspend)
+ "
+ [
+ activeProcess suspendWithState:#wait
+ ] ifCurtailed:[
+ "interrupts are not blocked when entered through Processor>>#interruptActive"
+ OperatingSystem blockInterrupts.
+ self removeWaitingProcess:activeProcess.
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ].
+ self removeWaitingProcess:activeProcess.
].
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- "Modified: 13.12.1995 / 13:26:49 / stefan"
- "Modified: 1.2.1997 / 12:11:41 / cg"
+ "Modified: / 13-12-1995 / 13:26:49 / stefan"
+ "Modified: / 24-07-2017 / 23:04:33 / cg"
!
waitUncountedWithTimeoutMs:milliSeconds
@@ -1046,6 +1048,23 @@
However, polling is not the intended use of semaphores, though.
If milliSeconds is nil, wait without timeout."
+ self waitUncountedWithTimeoutMs:milliSeconds state:#wait
+
+ "Modified: / 13-12-1995 / 13:27:24 / stefan"
+ "Modified: / 24-07-2017 / 21:53:57 / cg"
+!
+
+waitUncountedWithTimeoutMs:milliSeconds state:newStateSymbol
+ "wait for the semaphore; do not consume the resource
+ (i.e. do not count down).
+ Abort the wait after some time.
+ return the receiver if the semaphore triggered normal, nil if we return
+ due to a timeout.
+ With zero timeout, this can be used to poll a semaphore (returning
+ the receiver if the semaphore is available, nil if not).
+ However, polling is not the intended use of semaphores, though.
+ If milliSeconds is nil, wait without timeout."
+
|activeProcess timeoutOccurred wasBlocked timeoutBlock now endTime|
count > 0 ifTrue:[
@@ -1092,7 +1111,7 @@
"
[
"sleep until resumed..."
- activeProcess suspendWithState:#wait.
+ activeProcess suspendWithState:newStateSymbol.
] ifCurtailed:[
"interrupts are not blocked when entered through Processor>>#interruptActive"
OperatingSystem blockInterrupts.
@@ -1122,8 +1141,8 @@
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
^ self
- "Modified: / 13-12-1995 / 13:27:24 / stefan"
- "Modified: / 11-08-2011 / 14:37:00 / cg"
+ "Created: / 24-07-2017 / 21:53:23 / cg"
+ "Modified: / 24-07-2017 / 23:06:00 / cg"
!
waitWithTimeout:secondsOrNilOrTimeDuration
@@ -1148,9 +1167,10 @@
millis := (millis * 1000) asInteger
].
- ^ self waitWithTimeoutMs:millis.
+ ^ self waitWithTimeoutMs:millis state:#wait.
"Modified: / 21-02-2017 / 14:49:08 / stefan"
+ "Modified: / 24-07-2017 / 21:15:39 / cg"
!
waitWithTimeoutMs:milliSeconds
@@ -1162,86 +1182,10 @@
However, polling is not the intended use of semaphores, though.
If milliSeconds is nil, wait without timeout."
- |activeProcess timeoutOccurred wasBlocked timeoutBlock endTime|
-
- wasBlocked := OperatingSystem blockInterrupts.
-
- count <= 0 ifTrue:[
- "with zero-timeout, this is a poll"
- milliSeconds == 0 ifTrue:[
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ^ nil
- ].
-
- activeProcess := Processor activeProcess.
- timeoutOccurred := false.
-
- milliSeconds notNil ifTrue:[
- "Wait with timeout: calculate the end-time"
- endTime := OperatingSystem
- millisecondTimeAdd:OperatingSystem getMillisecondTime
- and:milliSeconds.
-
- timeoutBlock := [
- timeoutOccurred := true.
- timeoutBlock:= nil.
- Processor resume:activeProcess.
- ].
- Processor addTimedBlock:timeoutBlock for:activeProcess atMilliseconds:endTime.
- ].
-
- "
- need a while-loop here, since more than one process may
- wait for it and another one may also wake up.
- Thus, the count is not always non-zero after returning from
- suspend.
- "
- [
- self addWaitingProcess:activeProcess.
+ ^ self waitWithTimeoutMs:milliSeconds state:#wait
- "
- for some more descriptive info in processMonitor ...
- ... set the state to #wait (instead of #suspend)
- "
- [
- "sleep until resumed..."
- activeProcess suspendWithState:#wait.
- ] ifCurtailed:[
- "interrupts are not blocked when entered through Processor>>#interruptActive"
- OperatingSystem blockInterrupts.
- timeoutBlock notNil ifTrue:[
- Processor removeTimedBlock:timeoutBlock.
- timeoutBlock := nil.
- ].
- self removeWaitingProcess:activeProcess.
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ].
-
- self removeWaitingProcess:activeProcess.
- timeoutOccurred ifTrue:[
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ^ nil
- ].
-
- count <= 0
- ] whileTrue.
-
- timeoutBlock notNil ifTrue:[
- Processor removeTimedBlock:timeoutBlock.
- timeoutBlock := nil.
- ].
- ].
-
- "if we come here, we have acquired the semaphore"
- count := count - 1.
- count == 0 ifTrue:[
- lastOwnerId := Processor activeProcessId.
- ].
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ^ self
-
- "Modified: / 11-08-2011 / 14:37:00 / cg"
"Modified: / 21-02-2017 / 15:21:30 / stefan"
+ "Modified: / 24-07-2017 / 21:15:25 / cg"
!
waitWithTimeoutMs:milliSeconds state:waitStateSymbol
@@ -1335,6 +1279,7 @@
^ self
"Modified: / 21-02-2017 / 15:21:39 / stefan"
+ "Modified: / 24-07-2017 / 23:04:57 / cg"
! !
!Semaphore class methodsFor:'documentation'!