Class: Async::Semaphore

Inherits:
Object
  • Object
show all
Defined in:
lib/async/semaphore.rb

Overview

A synchronization primitive, which limits access to a given resource.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(limit = 1, parent: nil) ⇒ Semaphore

Returns a new instance of Semaphore.

[View source]

14
15
16
17
18
19
20
# File 'lib/async/semaphore.rb', line 14

def initialize(limit = 1, parent: nil)
	@count = 0
	@limit = limit
	@waiting = List.new
	
	@parent = parent
end

Instance Attribute Details

#countObject (readonly)

The current number of tasks that have acquired the semaphore.


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

def count
  @count
end

#limitObject

The maximum number of tasks that can acquire the semaphore.


26
27
28
# File 'lib/async/semaphore.rb', line 26

def limit
  @limit
end

#waitingObject (readonly)

The tasks waiting on this semaphore.


29
30
31
# File 'lib/async/semaphore.rb', line 29

def waiting
  @waiting
end

Instance Method Details

#acquireObject

Acquire the semaphore, block if we are at the limit. If no block is provided, you must call release manually.

[View source]

79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/async/semaphore.rb', line 79

def acquire
	wait
	
	@count += 1
	
	return unless block_given?
	
	begin
		return yield
	ensure
		self.release
	end
end

#async(*arguments, parent: (@parent or Task.current), **options) ⇒ Object

Run an async task. Will wait until the semaphore is ready until spawning and running the task.

[View source]

61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/async/semaphore.rb', line 61

def async(*arguments, parent: (@parent or Task.current), **options)
	wait
	
	parent.async(**options) do |task|
		@count += 1
		
		begin
			yield task, *arguments
		ensure
			self.release
		end
	end
end

#blocking?Boolean

Whether trying to acquire this semaphore would block.

Returns:

  • (Boolean)
[View source]

56
57
58
# File 'lib/async/semaphore.rb', line 56

def blocking?
	@count >= @limit
end

#empty?Boolean

Is the semaphore currently acquired?

Returns:

  • (Boolean)
[View source]

51
52
53
# File 'lib/async/semaphore.rb', line 51

def empty?
	@count.zero?
end

#releaseObject

Release the semaphore. Must match up with a corresponding call to ‘acquire`. Will release waiting fibers in FIFO order.

[View source]

94
95
96
97
98
99
100
# File 'lib/async/semaphore.rb', line 94

def release
	@count -= 1
	
	while (@limit - @count) > 0 and node = @waiting.first
		node.resume
	end
end