Class: Async::IO::Trap

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

Overview

A cross-reactor/process notification pipe.

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Trap

Returns a new instance of Trap.


31
32
33
34
35
36
37
# File 'lib/async/io/trap.rb', line 31

def initialize(name)
	@name = name
	@notifications = []
	
	@installed = false
	@mutex = Mutex.new
end

Instance Method Details

#async(parent: Task.current, **options, &block) ⇒ Object

In order to avoid blocking the reactor, specify `transient: true` as an option.


95
96
97
98
99
# File 'lib/async/io/trap.rb', line 95

def async(parent: Task.current, **options, &block)
	parent.async(**options) do |task|
		self.wait(task: task, &block)
	end
end

#default!Object


48
49
50
# File 'lib/async/io/trap.rb', line 48

def default!
	Signal.trap(@name, :DEFAULT)
end

#ignore!Object

Ignore the trap within the current process. Can be invoked before forking and/or invoking `install!` to assert default behaviour.


44
45
46
# File 'lib/async/io/trap.rb', line 44

def ignore!
	Signal.trap(@name, :IGNORE)
end

#install!Boolean

Install the trap into the current process. Thread safe.

Returns:

  • (Boolean)

    whether the trap was installed or not. If the trap was already installed, returns nil.


54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/async/io/trap.rb', line 54

def install!
	return if @installed
	
	@mutex.synchronize do
		return if @installed
		
		Signal.trap(@name, &self.method(:trigger))
		
		@installed = true
	end
	
	return true
end

#to_sObject


39
40
41
# File 'lib/async/io/trap.rb', line 39

def to_s
	"\#<#{self.class} #{@name}>"
end

#trigger(signal_number = nil) ⇒ void

This method returns an undefined value.

Signal all waiting tasks that the trap occurred.


103
104
105
# File 'lib/async/io/trap.rb', line 103

def trigger(signal_number = nil)
	@notifications.each(&:signal)
end

#wait(task: Task.current) {|Async::Task| ... } ⇒ Object Also known as: trap

Wait until the signal occurs. If a block is given, execute in a loop.

Yields:

  • (Async::Task)

    the current task.


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/async/io/trap.rb', line 70

def wait(task: Task.current, &block)
	task.annotate("waiting for signal #{@name}")
	
	notification = Notification.new
	@notifications << notification
	
	if block_given?
		while true
			notification.wait
			yield task
		end
	else
		notification.wait
	end
ensure
	if notification
		notification.close
		@notifications.delete(notification)
	end
end