Class: Multitrap::Trap

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

Constant Summary collapse

OWN_MRI_FRAME =
%r{/lib/multitrap/trap.rb:[0-9]{1,3}:in `block in store_trap'}
OWN_RBX_FRAME =
%r{/lib/multitrap/trap.rb:[0-9]{1,3}:in `store_trap'}
TRAVIS_FRAME =
%r{lib/jruby\.jar!/jruby/kernel/signal\.rb}
RESERVED_SIGNALS =
%w|BUS SEGV ILL FPE VTALRM|
KNOWN_SIGNALS =
Signal.list.keys - RESERVED_SIGNALS

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(original_trap) ⇒ Trap

Returns a new instance of Trap.



27
28
29
30
# File 'lib/multitrap/trap.rb', line 27

def initialize(original_trap)
  @original_trap = original_trap
  @trap_list = create_trap_list
end

Class Method Details

.__clear_all_handlers!Object



22
23
24
25
# File 'lib/multitrap/trap.rb', line 22

def self.__clear_all_handlers!
  @@multitrap ||= nil
  @@multitrap && @@multitrap.__clear_all_handlers!
end

.trap(original_trap, *args, &block) ⇒ Object



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

def self.trap(original_trap, *args, &block)
  @@multitrap ||= new(original_trap)

  signal = args[0]
  command = args[1]

  @@multitrap.store_trap(signal, command, &block)
end

Instance Method Details

#__clear_all_handlers!Object



62
63
64
65
66
67
68
# File 'lib/multitrap/trap.rb', line 62

def __clear_all_handlers!
  @trap_list.keys.select {|s| KNOWN_SIGNALS.include?(s) }.each do |signal|
    @original_trap.call(signal, 'DEFAULT')
  end

  @trap_list = create_trap_list
end

#store_trap(signal, command, &block) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/multitrap/trap.rb', line 32

def store_trap(signal, command, &block)
  signal = signal.to_s
  command ||= block

  trap_is_nested = nested_trap?

  if trap_is_nested
    # JRuby doesn't support nested traps.
    return if Multitrap.jruby?
    @trap_list[signal].pop
  end

  @trap_list[signal] << command

  prev_trap_handler = @original_trap.call(signal) do |signo|
    @trap_list[signal].reverse_each do |trap_handler|
      trap_handler.call(signo || Signal.list[signal])
    end
  end

  if !trap_is_nested &&
     @trap_list[signal].size == 1 &&
     !default_handler?(prev_trap_handler) &&
     !default_handler_path?(prev_trap_handler)
    @trap_list[signal].unshift(prev_trap_handler)
  end

  @trap_list
end