eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'RecursionLock':

Home

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

Class: RecursionLock


Inheritance:

   Object
   |
   +--AbstractLock
      |
      +--Semaphore
         |
         +--RecursionLock
            |
            +--Dolphin::Mutex

Package:
stx:libbasic
Category:
Kernel-Processes
Version:
rev: 1.62 date: 2022/03/31 08:57:24
user: stefan
file: RecursionLock.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


like a Semaphore for mutual exclusion, but avoids the deadlock
if a critical region is reentered by the same process again.
I.e. allows reentering the critical region IFF the current process
is the one which did the original locking.

WARNING:
    for now, recursionLocks are not unlocked when an image is
    restarted. You may have to recreate them to avoid a deadLock.
    (this may change in the future, but recreating a recursionLock in
     the #earlyRestart handling does not hurt)

copyright

COPYRIGHT (c) 1995 by Claus Gittinger 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.

Class protocol:

instance creation
o  name: aString
(comment from inherited method)
create & return a new semaphore which blocks until a signal is sent

o  name: aString owner: owningObject
(comment from inherited method)
create & return a new semaphore which blocks until a signal is sent

o  new
(comment from inherited method)
create & return a new semaphore which blocks until a signal is sent

o  new: n
(comment from inherited method)
create & return a new semaphore which allows n waits before blocking


Instance protocol:

blocked protocol
o  signalForAll
(comment from inherited method)
signal the semaphore for all waiters.
This can be used for process synchronization, if multiple processes are
waiting for a common event.

o  signalIf
(comment from inherited method)
signal the semaphore, but only if being waited upon.
This can be used for one-shot semaphores (i.e. not remembering
previous signals)

o  signalOnce
(comment from inherited method)
wakeup waiters - but only once.
I.e. if the semaphore has already been signaled, this is ignored.

o  waitUncounted
(comment from inherited method)
wait for the semaphore; do not consume the resource
(i.e. do not count down)

o  waitUncountedWithTimeoutMs: milliSeconds
(comment from inherited method)
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 milliSecondsOrNil is nil, wait without timeout.

queries
o  isOwnedByActiveProcess
answer true, if the activeProcess has already acquired the lock.

o  owner
return the owning processes (or nil)

o  wouldBlock
Check if the resource represented by the receiver is
already in use by another process.
Attention: if asked without some global lock (blockedInterrupts),
the returned value may be outdated right away.

signaling
o  signal
(comment from inherited method)
waking up the highest prio waiter.

waiting
o  critical: aBlock
evaluate aBlock as a critical region, but do not block
if this lock is already held by the current process.

o  critical: aBlock timeoutMs: timeoutMs ifBlocking: blockingBlock
like critical:, but do not block if the lock cannot be acquired
within timeoutMs milliseconds.
Instead, return the value of blockingBlock.

o  wait
wait, but do not block, if this lock is already held by the current process.
Answer false, if already locked, true if lock has been just acquired.

o  waitWithTimeoutMs: milliSeconds state: newState
wait, but do not block, if this lock is already held by the current process.
Answer false, if already locked, true if lock has been just acquired,
nil if the lock could not be acquired in time.


Examples:


example (good):
  |lock|

  lock := RecursionLock new.
  lock critical:[
      Transcript showCR:'in lock ...'.
      lock critical:[
          Transcript showCR:'again ...'
      ]
  ]
in contrast to (wrong example - deadlocks):
  |lock|

  lock := Semaphore forMutualExclusion.
  lock critical:[
      Transcript showCR:'in lock ...'.
      lock critical:[
          '*** never reached - deadlock because sema is already locked ***'.
          '    (press CTRL-c and abort in the debugger)'.
          Transcript showCR:'again ...'
      ]
  ]


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Tue, 10 Dec 2024 09:28:20 GMT