class Async::Waiter

A composable synchronization primitive, which allows one task to wait for a number of other tasks to complete. It can be used in conjunction with {Semaphore} and/or {Barrier}.

def async(parent: (@parent or Task.current), **options, &block)

@asynchronous Executes the given block concurrently.
Execute a child task and add it to the waiter.
def async(parent: (@parent or Task.current), **options, &block)
	parent.async(**options) do |task|
		yield(task)
	ensure
		@done << task
		@finished.signal
	end
end

def first(count = nil)

@returns [Async::Task] Otherwise, the first task to complete.
@returns [Array(Async::Task)] If an integer is given, the tasks which have completed.
@parameter count [Integer | Nil] The number of tasks to wait for.
Wait for the first `count` tasks to complete.
def first(count = nil)
	minimum = count || 1
	
	while @done.size < minimum
		@finished.wait
	end
	
	return @done.shift(*count)
end

def initialize(parent: nil, finished: Async::Condition.new)

@parameter finished [Async::Condition] The condition to signal when a task completes.
@parameter parent [Interface(:async) | Nil] The parent task to use for asynchronous operations.

Create a waiter instance.
def initialize(parent: nil, finished: Async::Condition.new)
	@finished = finished
	@done = []
	
	@parent = parent
end

def wait(count = nil)

@parameter count [Integer | Nil] The number of tasks to wait for.
Wait for the first `count` tasks to complete.
def wait(count = nil)
	if count
		first(count).map(&:wait)
	else
		first.wait
	end
end