lib/agent/selector.rb in agent-0.9.0 vs lib/agent/selector.rb in agent-0.9.1
- old
+ new
@@ -9,15 +9,10 @@
def self.select!
raise Errors::BlockMissing unless block_given?
selector = Selector.new
yield selector
selector.select
- ensure
- if selector
- selector.close_default_channel
- selector.dequeue_operations
- end
end
class Selector
attr_reader :cases
@@ -27,10 +22,12 @@
@ordered_cases = []
@cases = {}
@operations = {}
@blocking_once = BlockingOnce.new
@notifier = Notifier.new
+ @default_case = nil
+ @selected = false
end
def default(&blk)
if @default_case
raise Errors::DefaultCaseAlreadyDefinedError
@@ -45,16 +42,17 @@
add_case(s, :timeout, &blk)
end
def case(chan, direction, value=nil, &blk)
raise "invalid case, must be a channel" unless chan.is_a?(Channel)
- raise Errors::BlockMissing if blk.nil? && direction == :receive
raise Errors::InvalidDirection if direction != :send && direction != :receive
add_case(chan, direction, value, &blk)
end
def select
+ raise Errors::AlreadySelectedError if @selected
+
if !@ordered_cases.empty?
@ordered_cases.each do |cse|
if cse.direction == :send
@operations[cse.channel] << cse.channel.send(cse.value, :uuid => cse.uuid,
:blocking_once => @blocking_once,
@@ -74,23 +72,27 @@
@notifier.wait
execute_case(@notifier.payload)
end
+ ensure
+ @selected = true
+ close_default_channel
+ dequeue_operations
end
+
+ protected
+
def dequeue_operations
@operations.each do |channel, operations|
channel.remove_operations(operations)
end
end
def close_default_channel
@default_case.channel.close if @default_case
end
-
-
- protected
def add_case(chan, direction, value=nil, &blk)
uuid = UUID.generate
cse = Case.new(uuid, chan, direction, value, blk)
@ordered_cases << cse