Class: ReservedNames::Win32::Mutex

Inherits:
Object
  • Object
show all
Includes:
Chef::ReservedNames::Win32::API::Synchronization
Defined in:
lib/chef/win32/mutex.rb

Constant Summary

Constants included from Chef::ReservedNames::Win32::API::Synchronization

Chef::ReservedNames::Win32::API::Synchronization::DELETE, Chef::ReservedNames::Win32::API::Synchronization::INFINITE, Chef::ReservedNames::Win32::API::Synchronization::MUTEX_ALL_ACCESS, Chef::ReservedNames::Win32::API::Synchronization::MUTEX_MODIFY_STATE, Chef::ReservedNames::Win32::API::Synchronization::READ_CONTROL, Chef::ReservedNames::Win32::API::Synchronization::SYNCHRONIZE, Chef::ReservedNames::Win32::API::Synchronization::WAIT_ABANDONED, Chef::ReservedNames::Win32::API::Synchronization::WAIT_FAILED, Chef::ReservedNames::Win32::API::Synchronization::WAIT_OBJECT_0, Chef::ReservedNames::Win32::API::Synchronization::WAIT_TIMEOUT, Chef::ReservedNames::Win32::API::Synchronization::WRITE_DAC, Chef::ReservedNames::Win32::API::Synchronization::WRITE_OWNER

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Mutex

Returns a new instance of Mutex


27
28
29
30
# File 'lib/chef/win32/mutex.rb', line 27

def initialize(name)
  @name = name
  create_system_mutex
end

Instance Attribute Details

#handleObject (readonly)

Returns the value of attribute handle


32
33
34
# File 'lib/chef/win32/mutex.rb', line 32

def handle
  @handle
end

#nameObject (readonly)

Returns the value of attribute name


33
34
35
# File 'lib/chef/win32/mutex.rb', line 33

def name
  @name
end

Instance Method Details

#releaseObject

Releaes the mutex


72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/chef/win32/mutex.rb', line 72

def release
  # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685066(v=vs.85).aspx
  # Note that release method needs to be called more than once
  # if mutex is acquired more than once.
  unless ReleaseMutex(handle)
    # Don't fail things in here if we can't release the mutex.
    # Because it will be automatically released when the owner
    # of the process goes away and this class is only being used
    # to synchronize chef-clients runs on a node.
    Chef::Log.error("Can not release mutex '#{name}'. This might cause issues \
if other threads attempt to acquire the mutex.")
    Chef::ReservedNames::Win32::Error.raise!
  end
end

#testObject

Attempts to grab the mutex. Returns true if the mutex is grabbed or if it's already owned; false otherwise.


39
40
41
# File 'lib/chef/win32/mutex.rb', line 39

def test
  WaitForSingleObject(handle, 0) == WAIT_OBJECT_0
end

#waitObject

Attempts to grab the mutex and waits until it is acquired.


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/chef/win32/mutex.rb', line 45

def wait
  loop do
    wait_result = WaitForSingleObject(handle, 1000)
    case wait_result
    when WAIT_TIMEOUT
      # We are periodically waking up in order to give ruby a
      # chance to process any signal it got while we were
      # sleeping. This condition shouldn't contain any logic
      # other than sleeping.
      sleep 0.1
    when WAIT_ABANDONED
      # Previous owner of the mutex died before it can release the
      # mutex. Log a warning and continue.
      Chef::Log.debug "Existing owner of the mutex exited prematurely."
      break
    when WAIT_OBJECT_0
      # Mutex is successfully acquired.
      break
    else
      Chef::Log.error("Failed to acquire system mutex '#{name}'. Return code: #{wait_result}")
      Chef::ReservedNames::Win32::Error.raise!
    end
  end
end