"Semaphore.jist" package: jist.process; "includes Process, Processor, NativeMethodFailure" imports: jist.language.*; "includes Object, Boolean, SmallInteger, ..." imports: jist.utility.OrderedCollection; "include a specific class" public class Semaphore extends: Object [ "instance variables" protected SmallInteger signalCount := 0. protected OrderedCollection waitingProcesses := OrderedCollection new. private native signalNatively throws NativeMethodFailure. private native waitNatively throws NativeMethodFailure. "Answer whether there have been more signals than waits." public hasSignals ^Boolean [ ^( signalCount > 0 ) ] "Increment the receiver's signal count. If there are processes waiting on the semaphore, resume the longest waiting. Upon exit, interrupts are always enabled." public signal [ Exception context "build the context" catch: NativeMethodFailure with: [ : exception is NativeMethodFailure ! Process withoutInterruptsDo: [ ( signalCount := signalCount + 1 ) < 1 ifTrue: [ Processor resume: waitingProcesses removeFirst ] ] ]; "try a block that might throw an exception" try: [ self signalNatively ]. ] "Force the current process to be suspended until the receiver semaphore is signaled. Upon exit, interrupts are always enabled." public wait [ Processor currentProcessIsRecursive ifTrue: [ self error: 'wait not allowed during call-back' ]. Exception context catch: NativeMethodFailure with: [ : exception is NativeMethodFailure ! Process withoutInterruptsDo: [ ( signalCount := signalCount - 1 ) < 0 ifTrue: [ waitingProcesses addLast: Processor currentProcess. Processor suspendCurrentProcess. ] ] ]; try: [ self waitNatively ]. ] ]