Skip to content

Commit 9e75077

Browse files
Preallocate signal trap events.
Assisted-By: devx/3236e566-7538-432e-a30a-2bdf37265ed4
1 parent 48a4ff8 commit 9e75077

2 files changed

Lines changed: 25 additions & 7 deletions

File tree

lib/async/container/signals.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def call
3232
# @parameter events [Events] The queue used to receive signal events.
3333
def initialize(events = Events.new)
3434
@events = events
35-
@handlers = {}
35+
@traps = {}
3636
end
3737

3838
# @attribute [Events] The queue used to receive signal events.
@@ -42,7 +42,11 @@ def initialize(events = Events.new)
4242
# If no block is provided, the signal will be ignored while trapped.
4343
# @parameter signal [Symbol | String | Integer] The signal to trap.
4444
def trap(signal, &block)
45-
@handlers[signal] = block
45+
if block
46+
@traps[signal] = Event.new(signal, block).freeze
47+
else
48+
@traps[signal] = nil
49+
end
4650
end
4751

4852
# Ignore a signal while trapped.
@@ -62,8 +66,8 @@ def wait
6266
def trapped
6367
previous = {}
6468

65-
@handlers.each do |signal, handler|
66-
previous[signal] = install(signal, handler)
69+
@traps.each do |signal, event|
70+
previous[signal] = install(signal, event)
6771
end
6872

6973
yield self
@@ -75,10 +79,10 @@ def trapped
7579

7680
private
7781

78-
def install(signal, handler)
79-
if handler
82+
def install(signal, event)
83+
if event
8084
::Signal.trap(signal) do
81-
@events << Event.new(signal, handler)
85+
@events << event
8286
end
8387
else
8488
::Signal.trap(signal, "IGNORE")

test/async/container/signals.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@
7979
expect(applied).to be == true
8080
end
8181

82+
it "reuses a frozen event for trapped signals" do
83+
signals.trap(:USR1){}
84+
85+
signals.trapped do
86+
::Process.kill(:USR1, ::Process.pid)
87+
event = signals.wait
88+
89+
expect(event.frozen?).to be == true
90+
91+
::Process.kill(:USR1, ::Process.pid)
92+
expect(signals.wait).to be == event
93+
end
94+
end
95+
8296
it "ignores signals without a handler" do
8397
signals.trap(:USR1)
8498

0 commit comments

Comments
 (0)