Class: Win32::Semaphore

Inherits:
Ipc
  • Object
show all
Extended by:
Windows::Error, Windows::Handle, Windows::Synchronize
Defined in:
lib/win32/semaphore.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =
'0.3.0'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_count, max_count, name = nil, inherit = true) ⇒ Semaphore

Creates and returns new Semaphore object. If name is omitted, the Semaphore object is created without a name, i.e. it’s anonymous.

If name is provided and it already exists, then it is opened instead, and the initial_count and max_count parameters are ignored.

The initial_count and max_count parameters set the initial count and maximum count for the Semaphore object, respectively. See the documentation for the corresponding accessor for more information.

The inherit attribute determines whether or not the semaphore can be inherited by child processes.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/win32/semaphore.rb', line 48

def initialize(initial_count, max_count, name=nil, inherit=true)
   @initial_count = initial_count
   @max_count = max_count
   @name      = name
   @inherit   = inherit
   
   # Used to prevent potential segfaults.
   if name && !name.is_a?(String)
      raise TypeError, 'name must be a string'
   end
   
   if inherit
      sec = 0.chr * 12 # sizeof(SECURITY_ATTRIBUTES)
      sec[0,4] = [12].pack('L')
      sec[8,4] = [1].pack('L') # 1 == TRUE
   else
      sec = 0
   end
   
   handle = CreateSemaphore(sec, initial_count, max_count, name)
   
   if handle == 0 || handle == INVALID_HANDLE_VALUE
      raise Error, get_last_error
   end
 
   super(handle)
   
   if block_given?
      begin
         yield self
      ensure
         close
      end
   end
end

Instance Attribute Details

#initial_countObject (readonly)

The initial count for the semaphore object. This value must be greater than or equal to zero and less than or equal to max_count. The state of a semaphore is signaled when its count is greater than zero and nonsignaled when it is zero. The count is decreased by one whenever a wait function releases a thread that was waiting for the semaphore. The count is increased by a specified amount by calling Semaphore#release method.



23
24
25
# File 'lib/win32/semaphore.rb', line 23

def initial_count
  @initial_count
end

#max_countObject (readonly)

The maximum count for the semaphore object. This value must be greater than zero.



28
29
30
# File 'lib/win32/semaphore.rb', line 28

def max_count
  @max_count
end

#nameObject (readonly)

The name of the Semaphore object.



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

def name
  @name
end

Class Method Details

.open(name, inherit = true, &block) ⇒ Object

Open an existing Semaphore by name. The inherit argument sets whether or not the object was opened such that a process created by the CreateProcess() function (a Windows API function) can inherit the handle. The default is true.

This method is essentially identical to Semaphore.new, except that the options for initial_count and max_count cannot be set (since they are already set). Also, this method will raise a Semaphore::Error if the semaphore doesn’t already exist.

If you want “open or create” semantics, then use Semaphore.new. – The OpenSemaphore() call here is strictly to force an error if the user tries to open a semaphore that doesn’t already exist.



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/win32/semaphore.rb', line 99

def self.open(name, inherit=true, &block)
   if name && !name.is_a?(String)
      raise TypeError, 'name must be a string'
   end
   
   bool = inherit ? 1 : 0
   handle = OpenSemaphore(EVENT_ALL_ACCESS, bool, name)
   if handle == 0 || handle == INVALID_HANDLE_VALUE
      raise Error, get_last_error
   end
   CloseHandle(handle)

   self.new(0, 1, name, inherit, &block)
end

Instance Method Details

#inheritable?Boolean

Returns whether or not the object was opened such that a process created by the CreateProcess() function (a Windows API function) can inherit the handle. The default is true.

Returns:

  • (Boolean)


131
132
133
# File 'lib/win32/semaphore.rb', line 131

def inheritable?
   @inherit
end

#release(amount = 1) ⇒ Object

Increases the count of the specified semaphore object by amount. The default is 1. Returns the previous count of the semaphore if successful. If the amount exceeds the max_count specified when the semaphore was created then a Semaphore::Error is raised.



119
120
121
122
123
124
125
# File 'lib/win32/semaphore.rb', line 119

def release(amount = 1)
   pcount = [0].pack('L')
   unless ReleaseSemaphore(@handle, amount, pcount)
      raise Error, get_last_error   
   end
   pcount.unpack('L').first
end