Class: QuackConcurrency::ReentrantMutex
- Defined in:
- lib/quack_concurrency/reentrant_mutex.rb
Overview
ReentrantMutexs are similar to Mutexs with with the key distinction being that a thread can call lock on a Mutex that it has already locked.
Instance Method Summary collapse
-
#initialize ⇒ ReentrantMutex
constructor
Creates a new ReentrantMutex concurrency tool.
- #lock(&block) ⇒ Object
- #sleep(timeout = nil) ⇒ Object
-
#try_lock ⇒ Boolean
Attempts to obtain the lock and returns immediately.
- #unlock(&block) ⇒ Object
-
#unlock! { ... } ⇒ Object
Releases all lock, runs the block, then reacquires the same lock count when available, blocking if necessary.
Methods inherited from Mutex
#locked?, #locked_out?, #owned?, #owner, #synchronize, #waiting_threads_count
Constructor Details
#initialize ⇒ ReentrantMutex
Creates a new QuackConcurrency::ReentrantMutex concurrency tool.
12 13 14 15 |
# File 'lib/quack_concurrency/reentrant_mutex.rb', line 12 def initialize super @lock_depth = 0 end |
Instance Method Details
#lock ⇒ void #lock { ... } ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/quack_concurrency/reentrant_mutex.rb', line 30 def lock(&block) if block_given? lock start_depth = @lock_depth begin yield ensure ensure_can_unlock unless @lock_depth == start_depth raise ThreadError, 'Attempt to unlock a ReentrantMutex whose lock depth has been changed since locking it' end unlock end else super unless owned? @lock_depth += 1 nil end end |
#sleep(timeout = nil) ⇒ Object
51 52 53 54 55 56 |
# File 'lib/quack_concurrency/reentrant_mutex.rb', line 51 def sleep(timeout = nil) ensure_can_unlock base_depth do super(timeout) end end |
#try_lock ⇒ Boolean
Attempts to obtain the lock and returns immediately.
60 61 62 63 64 65 66 67 |
# File 'lib/quack_concurrency/reentrant_mutex.rb', line 60 def try_lock if owned? || super @lock_depth += 1 true else false end end |
#unlock ⇒ void #unlock { ... } ⇒ Object
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/quack_concurrency/reentrant_mutex.rb', line 80 def unlock(&block) ensure_can_unlock if block_given? temporarily_release(&block) else @lock_depth -= 1 super if @lock_depth == 0 nil end end |
#unlock! { ... } ⇒ Object
Releases all lock, runs the block, then reacquires the same lock count when available,
blocking if necessary.
98 99 100 101 102 103 |
# File 'lib/quack_concurrency/reentrant_mutex.rb', line 98 def unlock!(&block) ensure_can_unlock base_depth do temporarily_release(&block) end end |