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.



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

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.



78
79
80
81
82
# File 'lib/async/io/trap.rb', line 78

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

#default!Object



31
32
33
# File 'lib/async/io/trap.rb', line 31

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.



27
28
29
# File 'lib/async/io/trap.rb', line 27

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.



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/async/io/trap.rb', line 37

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



22
23
24
# File 'lib/async/io/trap.rb', line 22

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.



86
87
88
# File 'lib/async/io/trap.rb', line 86

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.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/async/io/trap.rb', line 53

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