class Concurrent::ReadWriteLock

def acquire_write_lock

Raises:
  • (Concurrent::ResourceLimitError) - if the maximum number of writers

Returns:
  • (Boolean) - true if the lock is successfully acquired
def acquire_write_lock
  while true
    c = @Counter.value
    raise ResourceLimitError.new('Too many writer threads') if max_writers?(c)
    if c == 0 # no readers OR writers running
      # if we successfully swap the RUNNING_WRITER bit on, then we can go ahead
      break if @Counter.compare_and_set(0, RUNNING_WRITER)
    elsif @Counter.compare_and_set(c, c+WAITING_WRITER)
      while true
        # Now we have successfully incremented, so no more readers will be able to increment
        #   (they will wait instead)
        # However, readers OR writers could decrement right here, OR another writer could increment
        @WriteLock.wait_until do
          # So we have to do another check inside the synchronized section
          # If a writer OR reader is running, then go to sleep
          c = @Counter.value
          !running_writer?(c) && !running_readers?(c)
        end
        # We just came out of a wait
        # If we successfully turn the RUNNING_WRITER bit on with an atomic swap,
        # Then we are OK to stop waiting and go ahead
        # Otherwise go back and wait again
        c = @Counter.value
        break if !running_writer?(c) && !running_readers?(c) && @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER)
      end
      break
    end
  end
  true
end