Class | Needle::QueryableMutex |
In: |
lib/needle/thread.rb
|
Parent: | Mutex |
A subclass of Mutex that allows clients to discover which thread has the mutex locked. This is necessary for (among other things) discovering cycles in the dependency graph of services.
Create a new unlocked QueryableMutex.
# File lib/needle/thread.rb, line 27 27: def initialize 28: super 29: @locking_thread = nil 30: end
Checks to see if the current thread has the mutex locked, and if it does, raises an exception. Otherwise, locks the mutex and sets the locking thread to Thread.current.
# File lib/needle/thread.rb, line 35 35: def lock 36: if @locking_thread == Thread.current 37: raise ThreadError, 38: "an attempt was made to reacquire an existing lock " + 39: "(this could happen if you have a circular dependency on a service)" 40: end 41: 42: while (Thread.critical = true; @locked) 43: @waiting.push Thread.current 44: Thread.stop 45: end 46: @locked = true 47: @locking_thread = Thread.current 48: Thread.critical = false 49: self 50: end
Return true if the current thread has locked this mutex.
# File lib/needle/thread.rb, line 87 87: def self_locked? 88: @locking_thread == Thread.current 89: end
Attempts to acquire the lock. Returns true if the lock was acquired, and false if the mutex was already locked.
# File lib/needle/thread.rb, line 54 54: def try_lock 55: result = false 56: Thread.critical = true 57: unless @locked 58: @locked = true 59: result = true 60: @locking_thread = Thread.current 61: end 62: Thread.critical = false 63: result 64: end
Unlocks the mutex and sets the locking thread to nil.
# File lib/needle/thread.rb, line 67 67: def unlock 68: return unless @locked 69: Thread.critical = true 70: @locked = false 71: begin 72: t = @waiting.shift 73: t.wakeup if t 74: rescue ThreadError 75: retry 76: end 77: @locking_thread = nil 78: Thread.critical = false 79: begin 80: t.run if t 81: rescue ThreadError 82: end 83: self 84: end