--- a/RecursionLock.st Fri Aug 25 10:06:39 2017 +0100
+++ b/RecursionLock.st Tue Aug 29 10:05:32 2017 +0100
@@ -13,8 +13,8 @@
"{ NameSpace: Smalltalk }"
-Object subclass:#RecursionLock
- instanceVariableNames:'process sema count'
+AbstractLock subclass:#RecursionLock
+ instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
category:'Kernel-Processes'
@@ -97,11 +97,19 @@
"same as new, for easy exchangability with regular mutual-exclusion Semaphores."
^ self new
-!
+! !
+
+!RecursionLock methodsFor:'acquire & release'!
-new
- ^ self basicNew initialize
+release
+ "
+ Release the lock.
+ "
+ super release ifFalse:[
+ self error: ('Calling process does not own the lock (caller: %1, owner: %2)' bindWith: Processor activeProcess id with: (process isNil ifTrue:['<no owner>'] ifFalse:[process id])).
+ ].
+ "Created: / 03-10-2017 / 13:06:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!RecursionLock methodsFor:'printing & storing'!
@@ -122,43 +130,10 @@
aGCOrStream nextPutAll:' name: '.
(self name ? 'unnamed') printOn:aGCOrStream.
aGCOrStream nextPut:$).
-!
-
-name
- "return the semaphores userFriendly name"
-
- ^ sema name
-
- "Created: / 28.6.1997 / 16:19:40 / cg"
- "Modified: / 14.12.1999 / 21:03:46 / cg"
-!
-
-name:aString
- "set the semaphores userFriendly name"
-
- sema name:aString
-
- "Created: / 28.6.1997 / 16:19:47 / cg"
- "Modified: / 14.12.1999 / 21:03:52 / cg"
-! !
-
-!RecursionLock methodsFor:'private-initialization'!
-
-initialize
- sema := Semaphore forMutualExclusion name:'RecursionLock@' , self identityHash printString.
- count := 0.
-
- "Modified: 25.1.1997 / 00:19:15 / cg"
! !
!RecursionLock methodsFor:'queries'!
-count
- ^ count
-
- "Created: / 28-08-2017 / 21:53:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
numberOfWaitingProcesses
"return the number of waiting processes"
@@ -167,12 +142,6 @@
"Created: 18.4.1996 / 17:18:08 / cg"
!
-owner
- "return the owning processes (or nil)"
-
- ^ process
-!
-
wouldBlock
"Check if the resource represented by the receiver is
already in use by another process.
@@ -186,35 +155,6 @@
!RecursionLock methodsFor:'signaling'!
-release
- "
- Release the lock. Return true of lock has been released, `false` if
- not (because calling process does not own it).
- "
- | active wasBlocked |
-
- active := Processor activeProcess.
- process == active ifFalse:[
- "/ Oops, calling thread does not own the monitor. return false
- "/ immediately. The caller is responsible for throwing
- "/ IllegalMonitorStateException...
- ^ false.
- ].
- wasBlocked := OperatingSystem blockInterrupts.
- count == 1 ifTrue:[
- process := nil.
- count := 0.
- sema signal.
- ] ifFalse:[
- count := count - 1.
- ].
- wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ].
- ^ true
-
-
- "Created: / 25-08-2017 / 08:38:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
signal
self breakPoint: #jv.
self release ifFalse:[
@@ -226,103 +166,6 @@
!RecursionLock methodsFor:'waiting'!
-acquire
- "
- Acquire the lock:
-
- * If the lock is not owned by any process, lock it and return immediately.
- * If the lock is already owned by the calling process, return immediately.
- * Otherwise, wait until owning process release it (by means of #release).
-
- Return `true` (always)
- "
- ^self acquireWithTimeoutMs: nil
-
-
- "Created: / 25-08-2017 / 08:34:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-acquireWithTimeoutMs: timeout
- "
- Acquire the lock:
-
- * If the lock is not owned by any process, lock it and return immediately.
- * If the lock is already owned by the calling process, return immediately.
- * Otherwise, wait until owning process release it (by means of #release)
- at most `timeout` milliseconds. If `timeout` is nil, wait forever.
-
- Return `true` if the lock has been acquired or `false` if bot (e.g. wait
- timed out)
- "
-
- | active wasBlocked acquired |
- acquired := nil.
- active := Processor activeProcess.
- process == active ifTrue:[
- "/ Process already ackquired the monitor, increase the
- "/ count and continue...
- count := count + 1.
- ^true.
- ].
- wasBlocked := OperatingSystem blockInterrupts.
- [
- (process notNil and:[ process isDead ]) ifTrue:[
- "/ Process that acquired the monitor died without releasing it.
- "/ This should not happen.
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- self assert: false description: 'Process that acquired the lock died without releasing it'.
- process := nil.
- count := 0.
- ].
- "/ We need to know that we already waited on and got semaphore
- "/ in case the Semaphore >> #wait is prematurely terminated.
- "/ Q: Can this actually happen? If so, how?
- acquired := sema waitWithTimeoutMs: timeout.
- process := active.
- count := 1.
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ] ifCurtailed:[
- acquired notNil ifTrue:[
- OperatingSystem blockInterrupts.
- count := 0.
- process := nil.
- sema signal.
- ].
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ].
- ^acquired notNil.
-
- "Created: / 25-08-2017 / 22:55:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-critical:aBlock
- "Evaluate aBlock as a critical region. Same process may
- enter critical region again, i.e., nesting allowed."
- ^self critical: aBlock timeoutMs: nil ifBlocking: nil
-
- "Modified (comment): / 25-08-2017 / 09:47:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-critical:aBlock ifBlocking:blockingBlock
- "Like #critical:, but do not block if the lock cannot be acquired.
- Instead, return the value of the second argument, `blockingBlock`."
-
- ^ self critical:aBlock timeoutMs:0 ifBlocking:blockingBlock.
-!
-
-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.`"
-
- | acquired |
- acquired := self acquireWithTimeoutMs: timeoutMs.
- acquired ifTrue:[
- ^ aBlock ensure:[ self release ]
- ] ifFalse:[
- ^ blockingBlock value.
- ].
-!
-
wait
self breakPoint: #jv.
self acquire.