EventSemaphore.st
author Claus Gittinger <cg@exept.de>
Tue, 09 Jul 2019 20:55:17 +0200
changeset 24417 03b083548da2
parent 23500 0d771b1d1860
permissions -rw-r--r--
#REFACTORING by exept class: Smalltalk class changed: #recursiveInstallAutoloadedClassesFrom:rememberIn:maxLevels:noAutoload:packageTop:showSplashInLevels: Transcript showCR:(... bindWith:...) -> Transcript showCR:... with:...

"{ Encoding: utf8 }"

"
 COPYRIGHT (c) 2016 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.  This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libbasic' }"

"{ NameSpace: Smalltalk }"

Semaphore subclass:#EventSemaphore
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Kernel-Processes'
!

!EventSemaphore class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2016 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.  This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    Processes wait for an EventSemaphores until it is signaled.
    The EventSemaphore is not consumed and remains signaled until manually reset.

    [author:]
        Stefan Vogel

    [see also:]
        Semaphore
"
!

example
"
    Create an event and signal it.
    After being signaled, the waiter on the event returns immediately.

                                [exBegin]
    |event|

    event := EventSemaphore new.
    [ event wait. Transcript showCR:'Process 1 continued' ] forkAt:9.
    [ event wait. Transcript showCR:'Process 2 continued' ] forkAt:9.
    event signal.
    event wait.
    event wait.
                                [exEnd]
"
! !

!EventSemaphore class methodsFor:'signaling'!

new:n
    "count must be 0 or 1"

    (n == 0 or:[n == 1]) ifTrue:[
        ^ super new:n.
    ].
    ^ self error:'invalid count'.

    "Modified: / 20-02-2017 / 10:27:06 / stefan"
! !

!EventSemaphore methodsFor:'blocked'!

signalForAll
    "blocked, since it would only set the event if there was anyone waiting"

    ^ self shouldNotImplement.
!

signalIf
    "blocked, since it would only set the event if there was anyone waiting"

    ^ self shouldNotImplement.
! !

!EventSemaphore methodsFor:'misc'!

reset
    "reset the event to the non-signaled state"

    count := 0
! !

!EventSemaphore methodsFor:'semaphoreSet interface'!

checkAndAddWaitingProcess:process
    "interface for SemaphoreSet.
     If the semaphore is available, return true.
     Otherwise register our process to be wakened up once the semaphore is available
     and return false.
     ATTENTION: this must be invoked with OperatingSystem-interrupts-blocked.
    "

    count > 0 ifTrue:[
        ^ true
    ].
    (waitingProcesses notNil and:[(waitingProcesses includesIdentical:process)]) ifFalse:[
        self addWaitingProcess:process.
    ].
    ^ false

    "Modified: / 14-12-1995 / 10:32:17 / stefan"
    "Modified: / 11-08-2011 / 14:36:20 / cg"
! !

!EventSemaphore methodsFor:'signaling'!

signal
    "redefined to limit count to 1"

    self signalOnce.
! !

!EventSemaphore methodsFor:'waiting'!

wait
    "once signaled, do not decrement the count"

    self waitUncounted
!

waitWithTimeoutMs:milliSeconds state:newState
    "wait for the semaphore, but 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.

     Redefined: once signaled, do not decrement the count"

    <resource: #skipInDebuggersWalkBack>

    ^ self waitUncountedWithTimeoutMs:milliSeconds state:newState.

    "Modified: / 24-07-2017 / 21:52:53 / cg"
    "Modified: / 30-05-2018 / 13:57:25 / Claus Gittinger"
    "Modified: / 01-11-2018 / 15:40:49 / Stefan Vogel"
! !

!EventSemaphore class methodsFor:'documentation'!

version
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
! !