| 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