summaryrefslogtreecommitdiffstats
path: root/lib/puppet/external/event-loop
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/external/event-loop')
-rw-r--r--lib/puppet/external/event-loop/better-definers.rb592
-rw-r--r--lib/puppet/external/event-loop/event-loop.rb548
-rw-r--r--lib/puppet/external/event-loop/signal-system.rb326
3 files changed, 733 insertions, 733 deletions
diff --git a/lib/puppet/external/event-loop/better-definers.rb b/lib/puppet/external/event-loop/better-definers.rb
index 0af37da62..09e33fdb5 100644
--- a/lib/puppet/external/event-loop/better-definers.rb
+++ b/lib/puppet/external/event-loop/better-definers.rb
@@ -18,350 +18,350 @@
# Boston, MA 02110-1301, USA.
class Symbol
- def predicate?
- to_s.include? "?" end
- def imperative?
- to_s.include? "!" end
- def writer?
- to_s.include? "=" end
-
- def punctuated?
- predicate? or imperative? or writer? end
- def without_punctuation
- to_s.delete("?!=").to_sym end
-
- def predicate
- without_punctuation.to_s + "?" end
- def imperative
- without_punctuation.to_s + "!" end
- def writer
- without_punctuation.to_s + "=" end
+ def predicate?
+ to_s.include? "?" end
+ def imperative?
+ to_s.include? "!" end
+ def writer?
+ to_s.include? "=" end
+
+ def punctuated?
+ predicate? or imperative? or writer? end
+ def without_punctuation
+ to_s.delete("?!=").to_sym end
+
+ def predicate
+ without_punctuation.to_s + "?" end
+ def imperative
+ without_punctuation.to_s + "!" end
+ def writer
+ without_punctuation.to_s + "=" end
end
class Hash
- def collect! (&block)
- replace Hash[*collect(&block).flatten]
- end
+ def collect! (&block)
+ replace Hash[*collect(&block).flatten]
+ end
- def flatten
- to_a.flatten
- end
+ def flatten
+ to_a.flatten
+ end
end
module Kernel
- def returning (value)
- yield value ; value
- end
+ def returning (value)
+ yield value ; value
+ end
end
class Module
- def define_hard_aliases (name_pairs)
- for new_aliases, existing_name in name_pairs do
- new_aliases.kind_of? Array or new_aliases = [new_aliases]
- for new_alias in new_aliases do
- alias_method(new_alias, existing_name)
- end
+ def define_hard_aliases (name_pairs)
+ for new_aliases, existing_name in name_pairs do
+ new_aliases.kind_of? Array or new_aliases = [new_aliases]
+ for new_alias in new_aliases do
+ alias_method(new_alias, existing_name)
+ end
+ end
end
- end
-
- def define_soft_aliases (name_pairs)
- for new_aliases, existing_name in name_pairs do
- new_aliases.kind_of? Array or new_aliases = [new_aliases]
- for new_alias in new_aliases do
- class_eval %{def #{new_alias}(*args, &block)
- #{existing_name}(*args, &block) end}
- end
+
+ def define_soft_aliases (name_pairs)
+ for new_aliases, existing_name in name_pairs do
+ new_aliases.kind_of? Array or new_aliases = [new_aliases]
+ for new_alias in new_aliases do
+ class_eval %{def #{new_alias}(*args, &block)
+ #{existing_name}(*args, &block) end}
+ end
+ end
end
- end
-
- define_soft_aliases \
- :define_hard_alias => :define_hard_aliases,
- :define_soft_alias => :define_soft_aliases
-
- # This method lets you define predicates like :foo?,
- # which will be defined to return the value of @foo.
- def define_readers (*names)
- for name in names.map { |x| x.to_sym } do
- if name.punctuated?
- # There's no way to define an efficient reader whose
- # name is different from the instance variable.
- class_eval %{def #{name} ; @#{name.without_punctuation} end}
- else
- # Use `attr_reader' to define an efficient method.
- attr_reader(name)
- end
+
+ define_soft_aliases \
+ :define_hard_alias => :define_hard_aliases,
+ :define_soft_alias => :define_soft_aliases
+
+ # This method lets you define predicates like :foo?,
+ # which will be defined to return the value of @foo.
+ def define_readers (*names)
+ for name in names.map { |x| x.to_sym } do
+ if name.punctuated?
+ # There's no way to define an efficient reader whose
+ # name is different from the instance variable.
+ class_eval %{def #{name} ; @#{name.without_punctuation} end}
+ else
+ # Use `attr_reader' to define an efficient method.
+ attr_reader(name)
+ end
+ end
end
- end
-
- def writer_defined? (name)
- method_defined? name.to_sym.writer
- end
-
- # If you pass a predicate symbol :foo? to this method, it'll first
- # define a regular writer method :foo, without a question mark.
- # Then it'll define an imperative writer method :foo! as a shorthand
- # for setting the property to true.
- def define_writers (*names, &body)
- for name in names.map { |x| x.to_sym } do
- if block_given?
- define_method(name.writer, &body)
- else
- attr_writer(name.without_punctuation)
- end
- if name.predicate?
- class_eval %{def #{name.imperative}
- self.#{name.writer} true end}
- end
+
+ def writer_defined? (name)
+ method_defined? name.to_sym.writer
end
- end
- define_soft_aliases \
- :define_reader => :define_readers,
- :define_writer => :define_writers
+ # If you pass a predicate symbol :foo? to this method, it'll first
+ # define a regular writer method :foo, without a question mark.
+ # Then it'll define an imperative writer method :foo! as a shorthand
+ # for setting the property to true.
+ def define_writers (*names, &body)
+ for name in names.map { |x| x.to_sym } do
+ if block_given?
+ define_method(name.writer, &body)
+ else
+ attr_writer(name.without_punctuation)
+ end
+ if name.predicate?
+ class_eval %{def #{name.imperative}
+ self.#{name.writer} true end}
+ end
+ end
+ end
- # We don't need a singular alias for `define_accessors',
- # because it always defines at least two methods.
+ define_soft_aliases \
+ :define_reader => :define_readers,
+ :define_writer => :define_writers
- def define_accessors (*names)
- define_readers(*names)
- define_writers(*names)
- end
+ # We don't need a singular alias for `define_accessors',
+ # because it always defines at least two methods.
- def define_opposite_readers (name_pairs)
- name_pairs.collect! { |k, v| [k.to_sym, v.to_sym] }
- for opposite_name, name in name_pairs do
- define_reader(name) unless method_defined? name
- class_eval %{def #{opposite_name} ; not #{name} end}
+ def define_accessors (*names)
+ define_readers(*names)
+ define_writers(*names)
end
- end
-
- def define_opposite_writers (name_pairs)
- name_pairs.collect! { |k, v| [k.to_sym, v.to_sym] }
- for opposite_name, name in name_pairs do
- define_writer(name) unless writer_defined? name
- class_eval %{def #{opposite_name.writer} x
- self.#{name.writer} !x end}
- class_eval %{def #{opposite_name.imperative}
- self.#{name.writer} false end}
+
+ def define_opposite_readers (name_pairs)
+ name_pairs.collect! { |k, v| [k.to_sym, v.to_sym] }
+ for opposite_name, name in name_pairs do
+ define_reader(name) unless method_defined? name
+ class_eval %{def #{opposite_name} ; not #{name} end}
+ end
end
- end
- define_soft_aliases \
- :define_opposite_reader => :define_opposite_readers,
- :define_opposite_writer => :define_opposite_writers
+ def define_opposite_writers (name_pairs)
+ name_pairs.collect! { |k, v| [k.to_sym, v.to_sym] }
+ for opposite_name, name in name_pairs do
+ define_writer(name) unless writer_defined? name
+ class_eval %{def #{opposite_name.writer} x
+ self.#{name.writer} !x end}
+ class_eval %{def #{opposite_name.imperative}
+ self.#{name.writer} false end}
+ end
+ end
+
+ define_soft_aliases \
+ :define_opposite_reader => :define_opposite_readers,
+ :define_opposite_writer => :define_opposite_writers
- def define_opposite_accessors (name_pairs)
- define_opposite_readers name_pairs
- define_opposite_writers name_pairs
- end
+ def define_opposite_accessors (name_pairs)
+ define_opposite_readers name_pairs
+ define_opposite_writers name_pairs
+ end
- def define_reader_with_opposite (name_pair, &body)
- name, opposite_name = name_pair.flatten.collect { |x| x.to_sym }
- define_method(name, &body)
- define_opposite_reader(opposite_name => name)
- end
+ def define_reader_with_opposite (name_pair, &body)
+ name, opposite_name = name_pair.flatten.collect { |x| x.to_sym }
+ define_method(name, &body)
+ define_opposite_reader(opposite_name => name)
+ end
- def define_writer_with_opposite (name_pair, &body)
- name, opposite_name = name_pair.flatten.collect { |x| x.to_sym }
- define_writer(name, &body)
- define_opposite_writer(opposite_name => name)
- end
+ def define_writer_with_opposite (name_pair, &body)
+ name, opposite_name = name_pair.flatten.collect { |x| x.to_sym }
+ define_writer(name, &body)
+ define_opposite_writer(opposite_name => name)
+ end
public :define_method
- def define_methods (*names, &body)
- names.each { |name| define_method(name, &body) }
- end
+ def define_methods (*names, &body)
+ names.each { |name| define_method(name, &body) }
+ end
- def define_private_methods (*names, &body)
- define_methods(*names, &body)
- names.each { |name| private name }
- end
-
- def define_protected_methods (*names, &body)
- define_methods(*names, &body)
- names.each { |name| protected name }
- end
-
- def define_private_method (name, &body)
- define_method(name, &body)
- private name
- end
-
- def define_protected_method (name, &body)
- define_method(name, &body)
- protected name
- end
+ def define_private_methods (*names, &body)
+ define_methods(*names, &body)
+ names.each { |name| private name }
+ end
+
+ def define_protected_methods (*names, &body)
+ define_methods(*names, &body)
+ names.each { |name| protected name }
+ end
+
+ def define_private_method (name, &body)
+ define_method(name, &body)
+ private name
+ end
+
+ def define_protected_method (name, &body)
+ define_method(name, &body)
+ protected name
+ end
end
class ImmutableAttributeError < StandardError
- def initialize (attribute=nil, message=nil)
- super message
- @attribute = attribute
- end
-
- define_accessors :attribute
-
- def to_s
- if @attribute and @message
- "cannot change the value of `#@attribute': #@message"
- elsif @attribute
- "cannot change the value of `#@attribute'"
- elsif @message
- "cannot change the value of attribute: #@message"
- else
- "cannot change the value of attribute"
+ def initialize (attribute=nil, message=nil)
+ super message
+ @attribute = attribute
+ end
+
+ define_accessors :attribute
+
+ def to_s
+ if @attribute and @message
+ "cannot change the value of `#@attribute': #@message"
+ elsif @attribute
+ "cannot change the value of `#@attribute'"
+ elsif @message
+ "cannot change the value of attribute: #@message"
+ else
+ "cannot change the value of attribute"
+ end
end
- end
end
class Module
- # Guard each of the specified attributes by replacing the writer
- # method with a proxy that asks the supplied block before proceeding
- # with the change.
- #
- # If it's okay to change the attribute, the block should return
- # either nil or the symbol :mutable. If it isn't okay, the block
- # should return a string saying why the attribute can't be changed.
- # If you don't want to provide a reason, you can have the block
- # return just the symbol :immutable.
- def guard_writers(*names, &predicate)
- for name in names.map { |x| x.to_sym } do
- define_hard_alias("__unguarded_#{name.writer}" => name.writer)
- define_method(name.writer) do |new_value|
- case result = predicate.call
- when :mutable, nil
- __send__("__unguarded_#{name.writer}", new_value)
- when :immutable
- raise ImmutableAttributeError.new(name)
- else
- raise ImmutableAttributeError.new(name, result)
+ # Guard each of the specified attributes by replacing the writer
+ # method with a proxy that asks the supplied block before proceeding
+ # with the change.
+ #
+ # If it's okay to change the attribute, the block should return
+ # either nil or the symbol :mutable. If it isn't okay, the block
+ # should return a string saying why the attribute can't be changed.
+ # If you don't want to provide a reason, you can have the block
+ # return just the symbol :immutable.
+ def guard_writers(*names, &predicate)
+ for name in names.map { |x| x.to_sym } do
+ define_hard_alias("__unguarded_#{name.writer}" => name.writer)
+ define_method(name.writer) do |new_value|
+ case result = predicate.call
+ when :mutable, nil
+ __send__("__unguarded_#{name.writer}", new_value)
+ when :immutable
+ raise ImmutableAttributeError.new(name)
+ else
+ raise ImmutableAttributeError.new(name, result)
+ end
+ end
end
- end
end
- end
- def define_guarded_writers (*names, &block)
- define_writers(*names)
- guard_writers(*names, &block)
- end
+ def define_guarded_writers (*names, &block)
+ define_writers(*names)
+ guard_writers(*names, &block)
+ end
- define_soft_alias :guard_writer => :guard_writers
- define_soft_alias :define_guarded_writer => :define_guarded_writers
+ define_soft_alias :guard_writer => :guard_writers
+ define_soft_alias :define_guarded_writer => :define_guarded_writers
end
if __FILE__ == $0
- require "test/unit"
-
- class DefineAccessorsTest < Test::Unit::TestCase
- def setup
- @X = Class.new
- @Y = Class.new @X
- @x = @X.new
- @y = @Y.new
- end
+ require "test/unit"
+
+ class DefineAccessorsTest < Test::Unit::TestCase
+ def setup
+ @X = Class.new
+ @Y = Class.new @X
+ @x = @X.new
+ @y = @Y.new
+ end
- def test_define_hard_aliases
- @X.define_method(:foo) { 123 }
- @X.define_method(:baz) { 321 }
- @X.define_hard_aliases :bar => :foo, :quux => :baz
- assert_equal @x.foo, 123
- assert_equal @x.bar, 123
- assert_equal @y.foo, 123
- assert_equal @y.bar, 123
- assert_equal @x.baz, 321
- assert_equal @x.quux, 321
- assert_equal @y.baz, 321
- assert_equal @y.quux, 321
- @Y.define_method(:foo) { 456 }
- assert_equal @y.foo, 456
- assert_equal @y.bar, 123
- @Y.define_method(:quux) { 654 }
- assert_equal @y.baz, 321
- assert_equal @y.quux, 654
- end
+ def test_define_hard_aliases
+ @X.define_method(:foo) { 123 }
+ @X.define_method(:baz) { 321 }
+ @X.define_hard_aliases :bar => :foo, :quux => :baz
+ assert_equal @x.foo, 123
+ assert_equal @x.bar, 123
+ assert_equal @y.foo, 123
+ assert_equal @y.bar, 123
+ assert_equal @x.baz, 321
+ assert_equal @x.quux, 321
+ assert_equal @y.baz, 321
+ assert_equal @y.quux, 321
+ @Y.define_method(:foo) { 456 }
+ assert_equal @y.foo, 456
+ assert_equal @y.bar, 123
+ @Y.define_method(:quux) { 654 }
+ assert_equal @y.baz, 321
+ assert_equal @y.quux, 654
+ end
- def test_define_soft_aliases
- @X.define_method(:foo) { 123 }
- @X.define_method(:baz) { 321 }
- @X.define_soft_aliases :bar => :foo, :quux => :baz
- assert_equal @x.foo, 123
- assert_equal @x.bar, 123
- assert_equal @y.foo, 123
- assert_equal @y.bar, 123
- assert_equal @x.baz, 321
- assert_equal @x.quux, 321
- assert_equal @y.baz, 321
- assert_equal @y.quux, 321
- @Y.define_method(:foo) { 456 }
- assert_equal @y.foo, @y.bar, 456
- @Y.define_method(:quux) { 654 }
- assert_equal @y.baz, 321
- assert_equal @y.quux, 654
- end
+ def test_define_soft_aliases
+ @X.define_method(:foo) { 123 }
+ @X.define_method(:baz) { 321 }
+ @X.define_soft_aliases :bar => :foo, :quux => :baz
+ assert_equal @x.foo, 123
+ assert_equal @x.bar, 123
+ assert_equal @y.foo, 123
+ assert_equal @y.bar, 123
+ assert_equal @x.baz, 321
+ assert_equal @x.quux, 321
+ assert_equal @y.baz, 321
+ assert_equal @y.quux, 321
+ @Y.define_method(:foo) { 456 }
+ assert_equal @y.foo, @y.bar, 456
+ @Y.define_method(:quux) { 654 }
+ assert_equal @y.baz, 321
+ assert_equal @y.quux, 654
+ end
- def test_define_readers
- @X.define_readers :foo, :bar
- assert !@x.respond_to?(:foo=)
- assert !@x.respond_to?(:bar=)
- @x.instance_eval { @foo = 123 ; @bar = 456 }
- assert_equal @x.foo, 123
- assert_equal @x.bar, 456
- @X.define_readers :baz?, :quux?
- assert !@x.respond_to?(:baz=)
- assert !@x.respond_to?(:quux=)
- @x.instance_eval { @baz = false ; @quux = true }
- assert !@x.baz?
- assert @x.quux?
- end
+ def test_define_readers
+ @X.define_readers :foo, :bar
+ assert !@x.respond_to?(:foo=)
+ assert !@x.respond_to?(:bar=)
+ @x.instance_eval { @foo = 123 ; @bar = 456 }
+ assert_equal @x.foo, 123
+ assert_equal @x.bar, 456
+ @X.define_readers :baz?, :quux?
+ assert !@x.respond_to?(:baz=)
+ assert !@x.respond_to?(:quux=)
+ @x.instance_eval { @baz = false ; @quux = true }
+ assert !@x.baz?
+ assert @x.quux?
+ end
- def test_define_writers
- assert !@X.writer_defined?(:foo)
- assert !@X.writer_defined?(:bar)
- @X.define_writers :foo, :bar
- assert @X.writer_defined?(:foo)
- assert @X.writer_defined?(:bar)
- assert @X.writer_defined?(:foo=)
- assert @X.writer_defined?(:bar=)
- assert @X.writer_defined?(:foo?)
- assert @X.writer_defined?(:bar?)
- assert !@x.respond_to?(:foo)
- assert !@x.respond_to?(:bar)
- @x.foo = 123
- @x.bar = 456
- assert_equal @x.instance_eval { @foo }, 123
- assert_equal @x.instance_eval { @bar }, 456
- @X.define_writers :baz?, :quux?
- assert !@x.respond_to?(:baz?)
- assert !@x.respond_to?(:quux?)
- @x.baz = true
- @x.quux = false
- assert_equal @x.instance_eval { @baz }, true
- assert_equal @x.instance_eval { @quux }, false
- end
+ def test_define_writers
+ assert !@X.writer_defined?(:foo)
+ assert !@X.writer_defined?(:bar)
+ @X.define_writers :foo, :bar
+ assert @X.writer_defined?(:foo)
+ assert @X.writer_defined?(:bar)
+ assert @X.writer_defined?(:foo=)
+ assert @X.writer_defined?(:bar=)
+ assert @X.writer_defined?(:foo?)
+ assert @X.writer_defined?(:bar?)
+ assert !@x.respond_to?(:foo)
+ assert !@x.respond_to?(:bar)
+ @x.foo = 123
+ @x.bar = 456
+ assert_equal @x.instance_eval { @foo }, 123
+ assert_equal @x.instance_eval { @bar }, 456
+ @X.define_writers :baz?, :quux?
+ assert !@x.respond_to?(:baz?)
+ assert !@x.respond_to?(:quux?)
+ @x.baz = true
+ @x.quux = false
+ assert_equal @x.instance_eval { @baz }, true
+ assert_equal @x.instance_eval { @quux }, false
+ end
- def test_define_accessors
- @X.define_accessors :foo, :bar
- @x.foo = 123 ; @x.bar = 456
- assert_equal @x.foo, 123
- assert_equal @x.bar, 456
- end
+ def test_define_accessors
+ @X.define_accessors :foo, :bar
+ @x.foo = 123 ; @x.bar = 456
+ assert_equal @x.foo, 123
+ assert_equal @x.bar, 456
+ end
- def test_define_opposite_readers
- @X.define_opposite_readers :foo? => :bar?, :baz? => :quux?
- assert !@x.respond_to?(:foo=)
- assert !@x.respond_to?(:bar=)
- assert !@x.respond_to?(:baz=)
- assert !@x.respond_to?(:quux=)
- @x.instance_eval { @bar = true ; @quux = false }
- assert !@x.foo?
- assert @x.bar?
- assert @x.baz?
- assert !@x.quux?
- end
+ def test_define_opposite_readers
+ @X.define_opposite_readers :foo? => :bar?, :baz? => :quux?
+ assert !@x.respond_to?(:foo=)
+ assert !@x.respond_to?(:bar=)
+ assert !@x.respond_to?(:baz=)
+ assert !@x.respond_to?(:quux=)
+ @x.instance_eval { @bar = true ; @quux = false }
+ assert !@x.foo?
+ assert @x.bar?
+ assert @x.baz?
+ assert !@x.quux?
+ end
- def test_define_opposite_writers
- @X.define_opposite_writers :foo? => :bar?, :baz => :quux
+ def test_define_opposite_writers
+ @X.define_opposite_writers :foo? => :bar?, :baz => :quux
+ end
end
- end
end
diff --git a/lib/puppet/external/event-loop/event-loop.rb b/lib/puppet/external/event-loop/event-loop.rb
index 17a520ead..75febab80 100644
--- a/lib/puppet/external/event-loop/event-loop.rb
+++ b/lib/puppet/external/event-loop/event-loop.rb
@@ -23,337 +23,337 @@ require "puppet/external/event-loop/signal-system"
require "fcntl"
class EventLoop
- include SignalEmitter
-
- IO_STATES = [:readable, :writable, :exceptional]
-
- class << self
- def default ; @default ||= new end
- def default= x ; @default = x end
-
- def current
- Thread.current["event-loop::current"] || default end
- def current= x
- Thread.current["event-loop::current"] = x end
-
- def with_current (new)
- if current == new
- yield
- else
- begin
- old = self.current
- self.current = new
- yield
- ensure
- self.current = old
+ include SignalEmitter
+
+ IO_STATES = [:readable, :writable, :exceptional]
+
+ class << self
+ def default ; @default ||= new end
+ def default= x ; @default = x end
+
+ def current
+ Thread.current["event-loop::current"] || default end
+ def current= x
+ Thread.current["event-loop::current"] = x end
+
+ def with_current (new)
+ if current == new
+ yield
+ else
+ begin
+ old = self.current
+ self.current = new
+ yield
+ ensure
+ self.current = old
+ end
+ end
+ end
+
+ def method_missing (name, *args, &block)
+ if current.respond_to? name
+ current.__send__(name, *args, &block)
+ else
+ super
+ end
end
- end
end
- def method_missing (name, *args, &block)
- if current.respond_to? name
- current.__send__(name, *args, &block)
- else
- super
- end
+ define_signals :before_sleep, :after_sleep
+
+ def initialize
+ @running = false
+ @awake = false
+ @wakeup_time = nil
+ @timers = []
+
+ @io_arrays = [[], [], []]
+ @ios = Hash.new do |h, k| raise ArgumentError,
+ "invalid IO event: #{k}", caller(2) end
+ IO_STATES.each_with_index { |x, i| @ios[x] = @io_arrays[i] }
+
+ @notify_src, @notify_snk = IO.pipe
+
+ # prevent file descriptor leaks
+ @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+ @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+
+ @notify_src.will_block = false
+ @notify_snk.will_block = false
+
+ # Each time a byte is sent through the notification pipe
+ # we need to read it, or IO.select will keep returning.
+ monitor_io(@notify_src, :readable)
+ @notify_src.extend(Watchable)
+ @notify_src.on_readable do
+ begin
+ @notify_src.sysread(256)
+ rescue Errno::EAGAIN
+ # The pipe wasn't readable after all.
+ end
+ end
end
- end
-
- define_signals :before_sleep, :after_sleep
-
- def initialize
- @running = false
- @awake = false
- @wakeup_time = nil
- @timers = []
-
- @io_arrays = [[], [], []]
- @ios = Hash.new do |h, k| raise ArgumentError,
- "invalid IO event: #{k}", caller(2) end
- IO_STATES.each_with_index { |x, i| @ios[x] = @io_arrays[i] }
-
- @notify_src, @notify_snk = IO.pipe
-
- # prevent file descriptor leaks
- @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
- @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
-
- @notify_src.will_block = false
- @notify_snk.will_block = false
-
- # Each time a byte is sent through the notification pipe
- # we need to read it, or IO.select will keep returning.
- monitor_io(@notify_src, :readable)
- @notify_src.extend(Watchable)
- @notify_src.on_readable do
- begin
- @notify_src.sysread(256)
- rescue Errno::EAGAIN
- # The pipe wasn't readable after all.
- end
+
+ define_opposite_accessors \
+ :stopped? => :running?,
+ :sleeping? => :awake?
+
+ def run
+ if block_given?
+ thread = Thread.new { run }
+ yield ; quit ; thread.join
+ else
+ running!
+ iterate while running?
+ end
+ ensure
+ quit
end
- end
-
- define_opposite_accessors \
- :stopped? => :running?,
- :sleeping? => :awake?
-
- def run
- if block_given?
- thread = Thread.new { run }
- yield ; quit ; thread.join
- else
- running!
- iterate while running?
+
+ def iterate (user_timeout=nil)
+ t1, t2 = user_timeout, max_timeout
+ timeout = t1 && t2 ? [t1, t2].min : t1 || t2
+ select(timeout).zip(IO_STATES) do |ios, state|
+ ios.each { |x| x.signal(state) } if ios
+ end
end
- ensure
- quit
- end
-
- def iterate (user_timeout=nil)
- t1, t2 = user_timeout, max_timeout
- timeout = t1 && t2 ? [t1, t2].min : t1 || t2
- select(timeout).zip(IO_STATES) do |ios, state|
- ios.each { |x| x.signal(state) } if ios
+
+ private
+
+ def select (timeout)
+ @wakeup_time = timeout ? Time.now + timeout : nil
+ # puts "waiting: #{timeout} seconds"
+ signal :before_sleep ; sleeping!
+ IO.select(*@io_arrays + [timeout]) || []
+ ensure
+ awake! ; signal :after_sleep
+ @timers.each { |x| x.sound_alarm if x.ready? }
end
- end
-
- private
-
- def select (timeout)
- @wakeup_time = timeout ? Time.now + timeout : nil
- # puts "waiting: #{timeout} seconds"
- signal :before_sleep ; sleeping!
- IO.select(*@io_arrays + [timeout]) || []
- ensure
- awake! ; signal :after_sleep
- @timers.each { |x| x.sound_alarm if x.ready? }
- end
-
- public
-
- def quit ; stopped! ; wake_up ; self end
-
- def monitoring_io? (io, event)
- @ios[event].include? io end
- def monitoring_timer? (timer)
- @timers.include? timer end
-
- def monitor_io (io, *events)
- for event in events do
- unless monitoring_io?(io, event)
- @ios[event] << io ; wake_up
- end
+
+ public
+
+ def quit ; stopped! ; wake_up ; self end
+
+ def monitoring_io? (io, event)
+ @ios[event].include? io end
+ def monitoring_timer? (timer)
+ @timers.include? timer end
+
+ def monitor_io (io, *events)
+ for event in events do
+ unless monitoring_io?(io, event)
+ @ios[event] << io ; wake_up
+ end
+ end
end
- end
- def monitor_timer (timer)
- unless monitoring_timer? timer
- @timers << timer
+ def monitor_timer (timer)
+ unless monitoring_timer? timer
+ @timers << timer
+ end
end
- end
- def check_timer (timer)
- wake_up if timer.end_time < @wakeup_time
- end
+ def check_timer (timer)
+ wake_up if timer.end_time < @wakeup_time
+ end
- def ignore_io (io, *events)
- events = IO_STATES if events.empty?
- for event in events do
- wake_up if @ios[event].delete(io)
+ def ignore_io (io, *events)
+ events = IO_STATES if events.empty?
+ for event in events do
+ wake_up if @ios[event].delete(io)
+ end
end
- end
- def ignore_timer (timer)
- # Don't need to wake up for this.
- @timers.delete(timer)
- end
+ def ignore_timer (timer)
+ # Don't need to wake up for this.
+ @timers.delete(timer)
+ end
- def max_timeout
- return nil if @timers.empty?
- [@timers.collect { |x| x.time_left }.min, 0].max
- end
+ def max_timeout
+ return nil if @timers.empty?
+ [@timers.collect { |x| x.time_left }.min, 0].max
+ end
- def wake_up
- @notify_snk.write('.') if sleeping?
- end
+ def wake_up
+ @notify_snk.write('.') if sleeping?
+ end
end
class Symbol
- def io_state?
- EventLoop::IO_STATES.include? self
- end
+ def io_state?
+ EventLoop::IO_STATES.include? self
+ end
end
module EventLoop::Watchable
- include SignalEmitter
+ include SignalEmitter
- define_signals :readable, :writable, :exceptional
+ define_signals :readable, :writable, :exceptional
- def monitor_events (*events)
- EventLoop.monitor_io(self, *events) end
- def ignore_events (*events)
- EventLoop.ignore_io(self, *events) end
+ def monitor_events (*events)
+ EventLoop.monitor_io(self, *events) end
+ def ignore_events (*events)
+ EventLoop.ignore_io(self, *events) end
- define_soft_aliases \
- :monitor_event => :monitor_events,
- :ignore_event => :ignore_events
+ define_soft_aliases \
+ :monitor_event => :monitor_events,
+ :ignore_event => :ignore_events
- def close ; super
- ignore_events end
- def close_read ; super
- ignore_event :readable end
- def close_write ; super
- ignore_event :writable end
+ def close ; super
+ ignore_events end
+ def close_read ; super
+ ignore_event :readable end
+ def close_write ; super
+ ignore_event :writable end
- module Automatic
- include EventLoop::Watchable
+ module Automatic
+ include EventLoop::Watchable
- def add_signal_handler (name, &handler) super
- monitor_event(name) if name.io_state?
- end
+ def add_signal_handler (name, &handler) super
+ monitor_event(name) if name.io_state?
+ end
- def remove_signal_handler (name, handler) super
- if @signal_handlers[name].empty?
- ignore_event(name) if name.io_state?
- end
+ def remove_signal_handler (name, handler) super
+ if @signal_handlers[name].empty?
+ ignore_event(name) if name.io_state?
+ end
+ end
end
- end
end
class IO
- def on_readable &block
- extend EventLoop::Watchable::Automatic
- on_readable(&block)
- end
-
- def on_writable &block
- extend EventLoop::Watchable::Automatic
- on_writable(&block)
- end
-
- def on_exceptional &block
- extend EventLoop::Watchable::Automatic
- on_exceptional(&block)
- end
-
- def will_block?
- require "fcntl"
- fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0
- end
-
- def will_block= (wants_blocking)
- require "fcntl"
- flags = fcntl(Fcntl::F_GETFL, 0)
- if wants_blocking
- flags &= ~Fcntl::O_NONBLOCK
- else
- flags |= Fcntl::O_NONBLOCK
+ def on_readable &block
+ extend EventLoop::Watchable::Automatic
+ on_readable(&block)
+ end
+
+ def on_writable &block
+ extend EventLoop::Watchable::Automatic
+ on_writable(&block)
+ end
+
+ def on_exceptional &block
+ extend EventLoop::Watchable::Automatic
+ on_exceptional(&block)
+ end
+
+ def will_block?
+ require "fcntl"
+ fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0
+ end
+
+ def will_block= (wants_blocking)
+ require "fcntl"
+ flags = fcntl(Fcntl::F_GETFL, 0)
+ if wants_blocking
+ flags &= ~Fcntl::O_NONBLOCK
+ else
+ flags |= Fcntl::O_NONBLOCK
+ end
+ fcntl(Fcntl::F_SETFL, flags)
end
- fcntl(Fcntl::F_SETFL, flags)
- end
end
class EventLoop::Timer
- include SignalEmitter
+ include SignalEmitter
- DEFAULT_INTERVAL = 0.0
- DEFAULT_TOLERANCE = 0.001
+ DEFAULT_INTERVAL = 0.0
+ DEFAULT_TOLERANCE = 0.001
- def initialize (options={}, &handler)
- @running = false
- @start_time = nil
+ def initialize (options={}, &handler)
+ @running = false
+ @start_time = nil
- if options.kind_of? Numeric
- options = { :interval => options }
- end
+ if options.kind_of? Numeric
+ options = { :interval => options }
+ end
+
+ if options[:interval]
+ @interval = options[:interval].to_f
+ else
+ @interval = DEFAULT_INTERVAL
+ end
- if options[:interval]
- @interval = options[:interval].to_f
- else
- @interval = DEFAULT_INTERVAL
+ if options[:tolerance]
+ @tolerance = options[:tolerance].to_f
+ elsif DEFAULT_TOLERANCE < @interval
+ @tolerance = DEFAULT_TOLERANCE
+ else
+ @tolerance = 0.0
+ end
+
+ @event_loop = options[:event_loop] || EventLoop.current
+
+ if block_given?
+ add_signal_handler(:alarm, &handler)
+ start unless options[:start?] == false
+ else
+ start if options[:start?]
+ end
end
- if options[:tolerance]
- @tolerance = options[:tolerance].to_f
- elsif DEFAULT_TOLERANCE < @interval
- @tolerance = DEFAULT_TOLERANCE
- else
- @tolerance = 0.0
+ define_readers :interval, :tolerance
+ define_signal :alarm
+
+ def stopped? ; @start_time == nil end
+ def running? ; @start_time != nil end
+
+ def interval= (new_interval)
+ old_interval = @interval
+ @interval = new_interval
+ if new_interval < old_interval
+ @event_loop.check_timer(self)
+ end
end
- @event_loop = options[:event_loop] || EventLoop.current
+ def end_time
+ @start_time + @interval end
+ def time_left
+ end_time - Time.now end
+ def ready?
+ time_left <= @tolerance end
- if block_given?
- add_signal_handler(:alarm, &handler)
- start unless options[:start?] == false
- else
- start if options[:start?]
+ def restart
+ @start_time = Time.now
end
- end
- define_readers :interval, :tolerance
- define_signal :alarm
+ def sound_alarm
+ signal :alarm
+ restart if running?
+ end
- def stopped? ; @start_time == nil end
- def running? ; @start_time != nil end
+ def start
+ @start_time = Time.now
+ @event_loop.monitor_timer(self)
+ end
- def interval= (new_interval)
- old_interval = @interval
- @interval = new_interval
- if new_interval < old_interval
- @event_loop.check_timer(self)
+ def stop
+ @start_time = nil
+ @event_loop.ignore_timer(self)
end
- end
-
- def end_time
- @start_time + @interval end
- def time_left
- end_time - Time.now end
- def ready?
- time_left <= @tolerance end
-
- def restart
- @start_time = Time.now
- end
-
- def sound_alarm
- signal :alarm
- restart if running?
- end
-
- def start
- @start_time = Time.now
- @event_loop.monitor_timer(self)
- end
-
- def stop
- @start_time = nil
- @event_loop.ignore_timer(self)
- end
end
if __FILE__ == $0
- require "test/unit"
+ require "test/unit"
- class TimerTest < Test::Unit::TestCase
- def setup
- @timer = EventLoop::Timer.new(:interval => 0.001)
- end
+ class TimerTest < Test::Unit::TestCase
+ def setup
+ @timer = EventLoop::Timer.new(:interval => 0.001)
+ end
- def test_timer
- @timer.on_alarm do
- puts "[#{@timer.time_left} seconds left after alarm]"
- EventLoop.quit
- end
- 8.times do
- t0 = Time.now
- @timer.start ; EventLoop.run
- t1 = Time.now
- assert(t1 - t0 > @timer.interval - @timer.tolerance)
- end
+ def test_timer
+ @timer.on_alarm do
+ puts "[#{@timer.time_left} seconds left after alarm]"
+ EventLoop.quit
+ end
+ 8.times do
+ t0 = Time.now
+ @timer.start ; EventLoop.run
+ t1 = Time.now
+ assert(t1 - t0 > @timer.interval - @timer.tolerance)
+ end
+ end
end
- end
end
## event-loop.rb ends here.
diff --git a/lib/puppet/external/event-loop/signal-system.rb b/lib/puppet/external/event-loop/signal-system.rb
index 2ca61e2ee..07feb9bf0 100644
--- a/lib/puppet/external/event-loop/signal-system.rb
+++ b/lib/puppet/external/event-loop/signal-system.rb
@@ -20,86 +20,86 @@
require "puppet/external/event-loop/better-definers"
module SignalEmitterModule
- def self.extended (object)
- if object.kind_of? Module and not object < SignalEmitter
- if object.respond_to? :fcall
- # This is the way to call private methods
- # in Ruby 1.9 as of November 16.
- object.fcall :include, SignalEmitter
- else
- object.__send__ :include, SignalEmitter
- end
- end
- end
-
- def define_signal (name, slot=:before, &body)
- # Can't use `define_method' and take a block pre-1.9.
- class_eval %{ def on_#{name} &block
+ def self.extended (object)
+ if object.kind_of? Module and not object < SignalEmitter
+ if object.respond_to? :fcall
+ # This is the way to call private methods
+ # in Ruby 1.9 as of November 16.
+ object.fcall :include, SignalEmitter
+ else
+ object.__send__ :include, SignalEmitter
+ end
+ end
+ end
+
+ def define_signal (name, slot=:before, &body)
+ # Can't use `define_method' and take a block pre-1.9.
+ class_eval %{ def on_#{name} &block
add_signal_handler(:#{name}, &block) end }
- define_signal_handler(name, :before, &lambda {|*a|})
- define_signal_handler(name, :after, &lambda {|*a|})
- define_signal_handler(name, slot, &body) if block_given?
- end
-
- def define_signals (*names, &body)
- names.each { |x| define_signal(x, &body) }
- end
-
- def define_signal_handler (name, slot=:before, &body)
- case slot
- when :before
- define_protected_method "handle_#{name}", &body
- when :after
- define_protected_method "after_handle_#{name}", &body
- else
- raise ArgumentError, "invalid slot `#{slot.inspect}'; " +
- "should be `:before' or `:after'", caller(1)
- end
- end
+ define_signal_handler(name, :before, &lambda {|*a|})
+ define_signal_handler(name, :after, &lambda {|*a|})
+ define_signal_handler(name, slot, &body) if block_given?
+ end
+
+ def define_signals (*names, &body)
+ names.each { |x| define_signal(x, &body) }
+ end
+
+ def define_signal_handler (name, slot=:before, &body)
+ case slot
+ when :before
+ define_protected_method "handle_#{name}", &body
+ when :after
+ define_protected_method "after_handle_#{name}", &body
+ else
+ raise ArgumentError, "invalid slot `#{slot.inspect}'; " +
+ "should be `:before' or `:after'", caller(1)
+ end
+ end
end
# This is an old name for the same thing.
SignalEmitterClass = SignalEmitterModule
module SignalEmitter
- def self.included (includer)
- if not includer.kind_of? SignalEmitterClass
- includer.extend SignalEmitterClass
- end
- end
-
- def __maybe_initialize_signal_emitter
- @signal_handlers ||= Hash.new { |h, k| h[k] = Array.new }
- @allow_dynamic_signals ||= false
- end
-
- define_accessors :allow_dynamic_signals?
-
- def add_signal_handler (name, &handler)
- __maybe_initialize_signal_emitter
- @signal_handlers[name] << handler
- return handler
- end
-
- define_soft_aliases [:on, :on_signal] => :add_signal_handler
-
- def remove_signal_handler (name, handler)
- __maybe_initialize_signal_emitter
- @signal_handlers[name].delete(handler)
- end
-
- def __signal__ (name, *args, &block)
- __maybe_initialize_signal_emitter
- respond_to? "on_#{name}" or allow_dynamic_signals? or
- fail "undefined signal `#{name}' for #{self}:#{self.class}"
- __send__("handle_#{name}", *args, &block) if
- respond_to? "handle_#{name}"
- @signal_handlers[name].each { |x| x.call(*args, &block) }
- __send__("after_handle_#{name}", *args, &block) if
- respond_to? "after_handle_#{name}"
- end
-
- define_soft_alias :signal => :__signal__
+ def self.included (includer)
+ if not includer.kind_of? SignalEmitterClass
+ includer.extend SignalEmitterClass
+ end
+ end
+
+ def __maybe_initialize_signal_emitter
+ @signal_handlers ||= Hash.new { |h, k| h[k] = Array.new }
+ @allow_dynamic_signals ||= false
+ end
+
+ define_accessors :allow_dynamic_signals?
+
+ def add_signal_handler (name, &handler)
+ __maybe_initialize_signal_emitter
+ @signal_handlers[name] << handler
+ return handler
+ end
+
+ define_soft_aliases [:on, :on_signal] => :add_signal_handler
+
+ def remove_signal_handler (name, handler)
+ __maybe_initialize_signal_emitter
+ @signal_handlers[name].delete(handler)
+ end
+
+ def __signal__ (name, *args, &block)
+ __maybe_initialize_signal_emitter
+ respond_to? "on_#{name}" or allow_dynamic_signals? or
+ fail "undefined signal `#{name}' for #{self}:#{self.class}"
+ __send__("handle_#{name}", *args, &block) if
+ respond_to? "handle_#{name}"
+ @signal_handlers[name].each { |x| x.call(*args, &block) }
+ __send__("after_handle_#{name}", *args, &block) if
+ respond_to? "after_handle_#{name}"
+ end
+
+ define_soft_alias :signal => :__signal__
end
# This module is indended to be a convenience mixin to be used by
@@ -113,108 +113,108 @@ end
# XXX: This has not seen much use, and I'd like to provide a
# better solution for the problem in the future.
module SignalObserver
- def __maybe_initialize_signal_observer
- @observed_signals ||= Hash.new do |signals, object|
- signals[object] = Hash.new do |handlers, name|
- handlers[name] = Array.new
- end
- end
- end
-
- def observe_signal (subject, name, &handler)
- __maybe_initialize_signal_observer
- @observed_signals[subject][name] << handler
- subject.add_signal_handler(name, &handler)
- end
-
- def map_signals (source, pairs={})
- pairs.each do |src_name, dst_name|
- observe_signal(source, src_name) do |*args|
- __signal__(dst_name, *args)
- end
- end
- end
-
- def absorb_signals (subject, *names)
- names.each do |name|
- observe_signal(subject, name) do |*args|
- __signal__(name, *args)
- end
- end
- end
-
- define_soft_aliases \
- :map_signal => :map_signals,
- :absorb_signal => :absorb_signals
-
- def ignore_signal (subject, name)
- __maybe_initialize_signal_observer
- __ignore_signal_1(subject, name)
- @observed_signals.delete(subject) if
- @observed_signals[subject].empty?
- end
-
- def ignore_signals (subject, *names)
- __maybe_initialize_signal_observer
- names = @observed_signals[subject] if names.empty?
- names.each { |x| __ignore_signal_1(subject, x) }
- end
-
- private
-
- def __ignore_signal_1(subject, name)
- @observed_signals[subject][name].each do |handler|
- subject.remove_signal_handler(name, handler) end
- @observed_signals[subject].delete(name)
- end
-end
+ def __maybe_initialize_signal_observer
+ @observed_signals ||= Hash.new do |signals, object|
+ signals[object] = Hash.new do |handlers, name|
+ handlers[name] = Array.new
+ end
+ end
+ end
-if __FILE__ == $0
- require "test/unit"
- class SignalEmitterTest < Test::Unit::TestCase
- class X
- include SignalEmitter
- define_signal :foo
+ def observe_signal (subject, name, &handler)
+ __maybe_initialize_signal_observer
+ @observed_signals[subject][name] << handler
+ subject.add_signal_handler(name, &handler)
end
- def setup
- @x = X.new
+ def map_signals (source, pairs={})
+ pairs.each do |src_name, dst_name|
+ observe_signal(source, src_name) do |*args|
+ __signal__(dst_name, *args)
+ end
+ end
end
- def test_on_signal
- moomin = 0
- @x.on_signal(:foo) { moomin = 1 }
- @x.signal :foo
- assert moomin == 1
+ def absorb_signals (subject, *names)
+ names.each do |name|
+ observe_signal(subject, name) do |*args|
+ __signal__(name, *args)
+ end
+ end
end
- def test_on_foo
- moomin = 0
- @x.on_foo { moomin = 1 }
- @x.signal :foo
- assert moomin == 1
+ define_soft_aliases \
+ :map_signal => :map_signals,
+ :absorb_signal => :absorb_signals
+
+ def ignore_signal (subject, name)
+ __maybe_initialize_signal_observer
+ __ignore_signal_1(subject, name)
+ @observed_signals.delete(subject) if
+ @observed_signals[subject].empty?
end
- def test_multiple_on_signal
- moomin = 0
- @x.on_signal(:foo) { moomin += 1 }
- @x.on_signal(:foo) { moomin += 2 }
- @x.on_signal(:foo) { moomin += 4 }
- @x.on_signal(:foo) { moomin += 8 }
- @x.signal :foo
- assert moomin == 15
+ def ignore_signals (subject, *names)
+ __maybe_initialize_signal_observer
+ names = @observed_signals[subject] if names.empty?
+ names.each { |x| __ignore_signal_1(subject, x) }
end
- def test_multiple_on_foo
- moomin = 0
- @x.on_foo { moomin += 1 }
- @x.on_foo { moomin += 2 }
- @x.on_foo { moomin += 4 }
- @x.on_foo { moomin += 8 }
- @x.signal :foo
- assert moomin == 15
+ private
+
+ def __ignore_signal_1(subject, name)
+ @observed_signals[subject][name].each do |handler|
+ subject.remove_signal_handler(name, handler) end
+ @observed_signals[subject].delete(name)
+ end
+end
+
+if __FILE__ == $0
+ require "test/unit"
+ class SignalEmitterTest < Test::Unit::TestCase
+ class X
+ include SignalEmitter
+ define_signal :foo
+ end
+
+ def setup
+ @x = X.new
+ end
+
+ def test_on_signal
+ moomin = 0
+ @x.on_signal(:foo) { moomin = 1 }
+ @x.signal :foo
+ assert moomin == 1
+ end
+
+ def test_on_foo
+ moomin = 0
+ @x.on_foo { moomin = 1 }
+ @x.signal :foo
+ assert moomin == 1
+ end
+
+ def test_multiple_on_signal
+ moomin = 0
+ @x.on_signal(:foo) { moomin += 1 }
+ @x.on_signal(:foo) { moomin += 2 }
+ @x.on_signal(:foo) { moomin += 4 }
+ @x.on_signal(:foo) { moomin += 8 }
+ @x.signal :foo
+ assert moomin == 15
+ end
+
+ def test_multiple_on_foo
+ moomin = 0
+ @x.on_foo { moomin += 1 }
+ @x.on_foo { moomin += 2 }
+ @x.on_foo { moomin += 4 }
+ @x.on_foo { moomin += 8 }
+ @x.signal :foo
+ assert moomin == 15
+ end
end
- end
end
## application-signals.rb ends here.