class RSpec::Support::Mutex

On 1.8.7, it’s in the stdlib. We don’t want to load the stdlib, b/c this is a test tool, and can affect the test environment, causing tests to pass where they should fail.

So we’re transcribing/modifying it from github.com/ruby/ruby/blob/v1_8_7_374/lib/thread.rb#L56 Some methods we don’t need are deleted. Anything I don’t understand (there’s quite a bit, actually) is left in.

Some formatting changes are made to appease the robot overlord:

https://travis-ci.org/rspec/rspec-core/jobs/54410874

@private

On 1.9 and up, this is in core, so we just use the real one

Constants

NEW_MUTEX_METHOD

If you mock Mutex.new you break our usage of Mutex, so instead we capture the original method to return Mutexs.

Public Class Methods

new() click to toggle source
# File lib/rspec/support/mutex.rb, line 16
def initialize
  @waiting = []
  @locked = false
  @waiting.taint
  taint
end
new() click to toggle source
# File lib/rspec/support/reentrant_mutex.rb, line 68
def self.new
  NEW_MUTEX_METHOD.call
end

Public Instance Methods

lock() click to toggle source

@private

# File lib/rspec/support/mutex.rb, line 24
def lock
  while Thread.critical = true && @locked
    @waiting.push Thread.current
    Thread.stop
  end
  @locked = true
  Thread.critical = false
  self
end
synchronize() { || ... } click to toggle source

@private

# File lib/rspec/support/mutex.rb, line 44
def synchronize
  lock
  begin
    yield
  ensure
    unlock
  end
end
unlock() click to toggle source

@private

# File lib/rspec/support/mutex.rb, line 35
def unlock
  return unless @locked
  Thread.critical = true
  @locked = false
  wakeup_and_run_waiting_thread
  self
end

Private Instance Methods

wakeup_and_run_waiting_thread() click to toggle source
# File lib/rspec/support/mutex.rb, line 55
def wakeup_and_run_waiting_thread
  begin
    t = @waiting.shift
    t.wakeup if t
  rescue ThreadError
    retry
  end
  Thread.critical = false
  begin
    t.run if t
  rescue ThreadError
    :noop
  end
end