Class: SafeFlock::Lockfile
- Inherits:
-
Object
- Object
- SafeFlock::Lockfile
- Defined in:
- lib/safe_flock/lockfile.rb
Overview
Thread-safe, transferable, flock-based lock file implementation
See create for a safe way to wrap the creation, locking and unlocking of the lock file.
Constant Summary collapse
- @@global_mutex =
Mutex.new
- @@path_mutex =
{}
Instance Attribute Summary collapse
-
#path ⇒ Object
readonly
The path to the lock file.
-
#pid ⇒ Object
readonly
The process that created the lock file.
-
#thread_id ⇒ Object
readonly
A unique identifier for the thread that created the lock file.
Instance Method Summary collapse
-
#initialize(path, max_wait: 5.0) ⇒ Lockfile
constructor
Initialize (but do not lock).
-
#lock ⇒ true|false
Lock the lock file.
-
#unlock ⇒ Object
Unlock the lock file.
Constructor Details
#initialize(path, max_wait: 5.0) ⇒ Lockfile
Initialize (but do not lock)
See SafeFlock.create for a safe way to wrap the creation, locking and unlocking of the lock file.
20 21 22 23 24 25 26 27 28 |
# File 'lib/safe_flock/lockfile.rb', line 20 def initialize(path, max_wait: 5.0) @pid = $$ @thread_id = Thread.current.object_id @path = path @max_wait = max_wait @wait_per_try = 0.1 @mlocked = false @lockfd = nil end |
Instance Attribute Details
#path ⇒ Object (readonly)
The path to the lock file
85 86 87 |
# File 'lib/safe_flock/lockfile.rb', line 85 def path @path end |
#pid ⇒ Object (readonly)
The process that created the lock file
90 91 92 |
# File 'lib/safe_flock/lockfile.rb', line 90 def pid @pid end |
#thread_id ⇒ Object (readonly)
A unique identifier for the thread that created the lock file
95 96 97 |
# File 'lib/safe_flock/lockfile.rb', line 95 def thread_id @thread_id end |
Instance Method Details
#lock ⇒ true|false
Lock the lock file
See SafeFlock.create for a safe way to wrap the creation, locking and unlocking of the lock file.
Attempt to File#flock the lock file, creating it if necessary.
If max_wait
is zero, the attempt is non-blocking: if the file is already locked, give up immediately. Otherwise, continue trying to lock the file for approximately max_wait
seconds.
The operation is performed under a per-path thread mutex to preserve mutual exclusion across threads.
49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/safe_flock/lockfile.rb', line 49 def lock deadline = Time.now.to_f + @max_wait while !(is_locked = try_lock) if Time.now.to_f < deadline sleep @wait_per_try else break end end is_locked end |
#unlock ⇒ Object
Unlock the lock file
See SafeFlock.create for a safe way to wrap the creation, locking and unlocking of the lock file.
Unlock the lock file in the current process.
The only intended use case for this method is in a forked child process that does significant work after the mutually exclusive work for which it required the lock. In such cases, the process may call unlock
after the mutually exclusive work is complete.
72 73 74 75 76 77 78 79 80 |
# File 'lib/safe_flock/lockfile.rb', line 72 def unlock if @lockfd @lockfd.close @lockfd = nil end if @mlocked && @pid == $$ and @thread_id == Thread.current.object_id mutex_unlock end end |