Parent

Class/Module Index [+]

Quicksearch

Rex::ReadWriteLock

This class implements a read/write lock synchronization primitive. It is meant to allow for more efficient access to resources that are more often read from than written to and many times can have concurrent reader threads. By allowing the reader threads to lock the resource concurrently rather than serially, a large performance boost can be seen. Acquiring a write lock results in exclusive access to the resource and thereby prevents any read operations during the time that a write lock is acquired. Only one write lock may be acquired at a time.

Public Class Methods

new() click to toggle source

Initializes a reader/writer lock instance.

# File lib/rex/sync/read_write_lock.rb, line 23
def initialize
        @read_sync_mutex  = Mutex.new
        @write_sync_mutex = Mutex.new
        @exclusive_mutex  = Mutex.new
        @readers          = 0
        @writer           = false
end

Public Instance Methods

lock_read() click to toggle source

Acquires the read lock for the calling thread.

# File lib/rex/sync/read_write_lock.rb, line 34
def lock_read
        read_sync_mutex.lock

        begin
                # If there are a non-zero number of readers and a
                # writer is waiting to acquire the exclusive lock,
                # free up the sync mutex temporarily and lock/unlock
                # the exclusive lock.  This is to give the writer
                # thread a chance to acquire the lock and prevents
                # it from being constantly starved.
                if ((@readers > 0) and
                    (@writer))
                        read_sync_mutex.unlock
                        exclusive_mutex.lock
                        exclusive_mutex.unlock
                        read_sync_mutex.lock
                end

                # Increment the active reader count
                @readers += 1

                # If we now have just one reader, acquire the exclusive
                # lock.  Track the thread owner so that we release the
                # lock from within the same thread context later on.
                if (@readers == 1)
                        exclusive_mutex.lock

                        @owner = Thread.current
                end
        ensure
                read_sync_mutex.unlock
        end
end
lock_write() click to toggle source

Acquire the exclusive write lock.

# File lib/rex/sync/read_write_lock.rb, line 113
def lock_write
        write_sync_mutex.lock

        begin
                @writer = true

                exclusive_mutex.lock

                @owner  = Thread.current
        ensure
                write_sync_mutex.unlock
        end
end
synchronize_read() click to toggle source

Synchronize a block for read access.

# File lib/rex/sync/read_write_lock.rb, line 146
def synchronize_read
        lock_read
        begin
                yield
        ensure
                unlock_read
        end
end
synchronize_write() click to toggle source

Synchronize a block for write access.

# File lib/rex/sync/read_write_lock.rb, line 158
def synchronize_write
        lock_write
        begin
                yield
        ensure
                unlock_write
        end
end
unlock_read() click to toggle source

Releases the read lock for the calling thread.

# File lib/rex/sync/read_write_lock.rb, line 71
def unlock_read
        read_sync_mutex.lock

        begin
                unlocked = false

                # Keep looping until we've lost this thread's reader
                # lock
                while (!unlocked)
                        # If there are no more readers left after this one
                        if (@readers - 1 == 0)
                                # If the calling thread is the owner of the exclusive
                                # reader lock, then let's release it
                                if (Thread.current == @owner)
                                        @owner = nil

                                        exclusive_mutex.unlock
                                end
                        # If there is more than one reader left and this thread is
                        # the owner of the exclusive lock, then keep looping so that
                        # we can eventually unlock the exclusive mutex in this thread's
                        # context
                        elsif (Thread.current == @owner)
                                read_sync_mutex.unlock

                                next
                        end

                        # Unlocked!
                        unlocked = true

                        # Decrement the active reader count
                        @readers -= 1
                end
        ensure
                read_sync_mutex.unlock
        end
end
unlock_write() click to toggle source

Release the exclusive write lock.

# File lib/rex/sync/read_write_lock.rb, line 130
def unlock_write
        # If the caller is not the owner of the write lock, then someone is
        # doing something broken, let's let them know.
        if (Thread.current != @owner)
                raise RuntimeError, "Non-owner calling thread attempted to release write lock", caller
        end

        # Otherwise, release the exclusive write lock
        @writer = false

        exclusive_mutex.unlock
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.