eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'BoltLock':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: BoltLock


Inheritance:

   Object
   |
   +--BoltLock

Package:
stx:libbasic2
Category:
Kernel-Processes
Version:
rev: 1.7 date: 2017/02/07 23:43:58
user: cg
file: BoltLock.st directory: libbasic2
module: stx stc-classLibrary: libbasic2
Author:
Claus Gittinger

Description:


A BoltLock (aka BoltVariable) is a 3-state semaphore, 
useful to protect a resource against single writers, while allowing multiple
readers to access the resource simultaneously.

The lock is in one of 3 states:
    A; free - can be changed by a writer into the locked state, or by a reader
              into the busy state.

    B; busy - can only be entered by another reader. left into free by last reader.

    C; locked  - a single writer has the lock; no other reader or writer is allowed
                 to acquire it

[notice:]
    the original BoltLock was unfair in that new incoming readers could lock up a waiting writer.
    This has been fixed by adding a fourth state (wantToLock), which is set by a write-waiter to prevent
    new readers from getting the lock.

[instance variables:]
    state                   <Symbol>

    numReaders              <Integer>               number of readers holding onto the lock

    waitingProcesses        <OrderedCollection>     waiting processes - will be served first
                                                    come first served when signalled.

    name                    <String>                a debugging aid: an optional userFriendly
                                                    name; helps to identify a semaphore easier.


Related information:

    Semaphore
    SemaphoreSet
    RecursionLock
    Monitor
    SharedQueue
    Delay
    Process
    ProcessorScheduler

Class protocol:

class initialization
o  initialize
(comment from inherited method)
called only once - initialize signals

instance creation
o  new
return an initialized instance


Instance protocol:

initialization
o  initialize
Invoked when a new instance is created.

private
o  addWaitingProcess: aProcess
add aProcess to the list of waiting processes.
all processes are ordered first-come-first-serve.

NOTE: must be called with blocked interrupts

o  removeWaitingProcess: aProcess
remove aProcess from the list of waiting processes
NO action if it is not in the list.

NOTE: must be called with blocked interrupts

o  wakeupWaiters
remove all waiting processes from the list of waiting processes
and resume them.
NOTE: Must be called when known that waitingProcesses is nonNil and
also with blocked interrupts

waiting
o  release
release the lock
usage example(s):
Transcript showCR:'  release in state ',state.

o  waitForRead
wait for the lock in order to read
usage example(s):
Transcript showCR:'  waitForRead in state ',state.

o  waitForWrite
wait for the lock in order to read
usage example(s):
Transcript showCR:'  waitForWrite in state ',state.


Examples:


many processes synchronizing on a boltLock:
    |lock readers readWriters currentWriter processes|

    lock := BoltLock new.

    readWriters := (1 to:10) collect:[:tNo |
                    [
                        10 timesRepeat:[
                            (Random nextIntegerBetween:1 and:6) == 1 ifTrue:[
                                Transcript showCR:('thread %1: want to write...' bindWith:tNo).
                                lock waitForWrite.
                                currentWriter notNil ifTrue:[Transcript showCR:('ouch %1: writer is %2' bindWith:tNo with:currentWriter).self halt].
                                currentWriter := tNo.
                                Transcript showCR:('thread %1: **** write' bindWith:tNo).
                                Delay waitForSeconds:(Random nextIntegerBetween:1 and:4).
                                Transcript showCR:('thread %1: done writing.' bindWith:tNo).
                                currentWriter := nil.
                                lock release.
                                Delay waitForSeconds:(Random nextIntegerBetween:1 and:4).
                            ] ifFalse:[
                                Transcript showCR:('thread %1: want to read...' bindWith:tNo).
                                lock waitForRead.
                                currentWriter notNil ifTrue:[Transcript showCR:('ouch %1: writer is %2' bindWith:tNo with:currentWriter).self halt].
                                Transcript showCR:('thread %1: ---- read' bindWith:tNo).
                                Delay waitForSeconds:(Random nextIntegerBetween:1 and:4).
                                Transcript showCR:('thread %1: done reading.' bindWith:tNo).
                                lock release.
                                Delay waitForSeconds:(Random nextIntegerBetween:1 and:4).
                            ].
                        ].
                        Transcript showCR:('thread %1: finished.').
                   ] newProcess name:('rw%1' bindWith:tNo).
                ].

    readers := (11 to:20) collect:[:tNo |
                    [
                        10 timesRepeat:[
                            Transcript showCR:('thread %1: want to read...' bindWith:tNo).
                            lock waitForRead.
                            currentWriter notNil ifTrue:[Transcript showCR:('ouch %1: writer is %2' bindWith:tNo with:currentWriter).self halt].
                            Transcript showCR:('thread %1: ---- read' bindWith:tNo).
                            Delay waitForSeconds:(Random nextIntegerBetween:1 and:4).
                            Transcript showCR:('thread %1: done.' bindWith:tNo).
                            lock release.
                            Delay waitForSeconds:(Random nextIntegerBetween:1 and:4).
                        ].
                        Transcript showCR:('thread %1: finished.').
                   ] newProcess name:('r%1' bindWith:tNo).
                ].

    processes := readWriters , readers.
    readWriters do:[:t | t resume].
    readers do:[:t | t resume].


ST/X 7.1.0.0; WebServer 1.663 at exept.de:8081; Thu, 19 Jul 2018 06:06:10 GMT