Class: ReentrantFlock
- Inherits:
-
Object
- Object
- ReentrantFlock
- Defined in:
- lib/reentrant_flock.rb,
lib/reentrant_flock.rb,
lib/reentrant_flock.rb,
lib/reentrant_flock/version.rb
Overview
Please note that:
“‘ fp = File.open(’a’, ‘w’) fp.flock(File::LOCK_EX) fp.flock(File::LOCK_EX) # does not block fp = File.open(‘a’, ‘w’) fp.flock(File::LOCK_EX) # block “‘
That is, File#flock is orginally reentrant for the same file object. On linux, file lock is associated with file descriptor, so another file descriptor is required to get blocked. This version holds the same file object, so might be useless. I may delete this. Using flock directly should be enough.
Defined Under Namespace
Classes: AlreadyLocked
Constant Summary collapse
- VERSION =
"0.1.1"
Instance Attribute Summary collapse
-
#fp ⇒ Object
readonly
Returns the value of attribute fp.
Class Method Summary collapse
-
.flock(fp, operation) ⇒ Object
Note that File#flock is automatically unlocked when a file is closed, but ReentrantFlock.flock cannot automatically reset internal counts when a file is closed.
-
.self_locked?(fp) ⇒ Boolean
True if locked by self.
-
.synchronize(fp, operation) { ... } ⇒ Object
The result of block.
Instance Method Summary collapse
-
#flock(operation) ⇒ Object
See File#flock.
-
#initialize(fp) ⇒ ReentrantFlock
constructor
A new instance of ReentrantFlock.
-
#self_locked? ⇒ Boolean
True if locked by self.
-
#synchronize(operation) { ... } ⇒ Object
The result of block.
Constructor Details
#initialize(fp) ⇒ ReentrantFlock
Returns a new instance of ReentrantFlock.
110 111 112 113 114 |
# File 'lib/reentrant_flock.rb', line 110 def initialize(fp) @fp = fp @mutex = Mutex.new @counts = Hash.new(0) end |
Instance Attribute Details
#fp ⇒ Object (readonly)
Returns the value of attribute fp.
108 109 110 |
# File 'lib/reentrant_flock.rb', line 108 def fp @fp end |
Class Method Details
.flock(fp, operation) ⇒ Object
Note that File#flock is automatically unlocked when a file is closed, but ReentrantFlock.flock cannot automatically reset internal counts when a file is closed. Use ReentrantFlock.synchronize to assure decrementing internal counts.
17 18 19 20 21 22 23 |
# File 'lib/reentrant_flock.rb', line 17 def flock(fp, operation) if (operation & File::LOCK_UN) > 0 unlock(fp) else lock(fp, operation) end end |
.self_locked?(fp) ⇒ Boolean
Returns true if locked by self.
43 44 45 46 |
# File 'lib/reentrant_flock.rb', line 43 def self_locked?(fp) k = key(fp) Thread.current.key?(k) and Thread.current[k] >= 1 end |
.synchronize(fp, operation) { ... } ⇒ Object
Returns the result of block.
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/reentrant_flock.rb', line 30 def synchronize(fp, operation) raise 'Must be called with a block' unless block_given? begin raise AlreadyLocked if lock(fp, operation) == false yield ensure unlock(fp) end end |
Instance Method Details
#flock(operation) ⇒ Object
Returns see File#flock.
118 119 120 121 122 123 124 |
# File 'lib/reentrant_flock.rb', line 118 def flock(operation) if (operation & File::LOCK_UN) > 0 unlock else lock(operation) end end |
#self_locked? ⇒ Boolean
Returns true if locked by self.
142 143 144 |
# File 'lib/reentrant_flock.rb', line 142 def self_locked? @mutex.synchronize { @counts[Thread.current] >= 1 } end |
#synchronize(operation) { ... } ⇒ Object
Returns the result of block.
130 131 132 133 134 135 136 137 138 139 |
# File 'lib/reentrant_flock.rb', line 130 def synchronize(operation) raise 'Must be called with a block' unless block_given? begin raise AlreadyLocked if lock(operation) == false yield ensure unlock end end |