Class: Tsafe::Mrswlock
- Inherits:
-
Object
- Object
- Tsafe::Mrswlock
- Defined in:
- lib/tsafe_mrswlock.rb,
lib/tsafe_mrswlock_jruby.rb
Overview
A class that allows many simultanious read-synchronizations but locks both reading and writing while calling the write-synchronzie-method. This is the JRuby-version and will not work under anything else. It uses ‘java.util.concurrent.locks.ReentrantReadWriteLock’ instead of doing the locking in Ruby.
Instance Method Summary collapse
-
#initialize ⇒ Mrswlock
constructor
Sets various variables.
-
#rsync ⇒ Object
Runs the given block through the read-synchronization.
-
#wsync ⇒ Object
Runs the given block through the write-synchronization (locks both reading and writing).
Constructor Details
#initialize ⇒ Mrswlock
Sets various variables.
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/tsafe_mrswlock.rb', line 6 def initialize @reads = 0 @w_mutex = Mutex.new #This variable is used to allow reads from the writing thread (monitor-behavior). @locked_by = nil #This hash holds thread-IDs for threads that are reading. @reading_threads = {} end |
Instance Method Details
#rsync ⇒ Object
Runs the given block through the read-synchronization.
18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/tsafe_mrswlock.rb', line 18 def rsync begin tid = Thread.current.__id__ Thread.pass while @w_mutex.locked? and @locked_by != tid @reading_threads[tid] = true @reads += 1 yield ensure @reading_threads.delete(tid) @reads -= 1 end end |
#wsync ⇒ Object
Runs the given block through the write-synchronization (locks both reading and writing).
Examples
lock.wsync do
#do something within lock.
end
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/tsafe_mrswlock.rb', line 36 def wsync @w_mutex.synchronize do begin tid = Thread.current.__id__ @locked_by = tid #Wait for any reads to finish that might have started while we were getting the lock. #Also allow write if there is only one reading thread and that reading thread is the current thread. while @reads > 0 raise ThreadError, "Deadlock: Writing is not allowed while reading." if @reading_threads.key?(tid) Thread.pass end yield ensure @locked_by = nil end end end |