summaryrefslogtreecommitdiff
path: root/ractor.rb
diff options
context:
space:
mode:
Diffstat (limited to 'ractor.rb')
-rw-r--r--ractor.rb126
1 files changed, 5 insertions, 121 deletions
diff --git a/ractor.rb b/ractor.rb
index 5620eeec38..d18062ca07 100644
--- a/ractor.rb
+++ b/ractor.rb
@@ -358,129 +358,13 @@ class Ractor
def self.select(*ractors, yield_value: yield_unspecified = true, move: false)
raise ArgumentError, 'specify at least one ractor or `yield_value`' if yield_unspecified && ractors.empty?
- begin
- if ractors.delete Ractor.current
- do_receive = true
- else
- do_receive = false
- end
- selector = Ractor::Selector.new(*ractors)
-
- if yield_unspecified
- selector.wait receive: do_receive
- else
- selector.wait receive: do_receive, yield_value: yield_value, move: move
- end
- ensure
- selector.clear
- end
- end
-
- #
- # Ractor::Selector provides a functionality to wait multiple Ractor events.
- # Ractor::Selector#wait is more lightweight than Ractor.select()
- # because we don't have to specify all target ractors for each wait time.
- #
- # Ractor.select() uses Ractor::Selector internally to implement it.
- #
- class Selector
- # call-seq:
- # Ractor::Selector.new(*ractors)
- #
- # Creates a selector object.
- #
- # If a ractors parameter is given, it is same as the following code.
- #
- # selector = Ractor::Selector.new
- # ractors.each{|r| selector.add r}
- #
- def self.new(*rs)
- selector = __builtin_cexpr! %q{
- ractor_selector_create(self);
- }
- rs.each{|r| selector.add(r) }
- selector
- end
-
- # call-seq:
- # selector.add(ractor)
- #
- # Registers a ractor as a taking target by the selector.
- #
- def add r
- __builtin_ractor_selector_add r
- end
-
- # call-seq:
- # selector.remove(ractor)
- #
- # Deregisters a ractor as a taking target by the selector.
- #
- def remove r
- __builtin_ractor_selector_remove r
- end
-
- # call-seq:
- # selector.clear
- #
- # Deregisters all ractors.
- def clear
- __builtin_ractor_selector_clear
- end
-
- # call-seq:
- # selector.empty?
- #
- # Returns true if the number of ractors in the waiting set at the current time is zero.
- #
- # Note that even if <tt>#empty?</tt> returns false, the subsequent <tt>#wait</tt>
- # may raise an exception because other ractors may close the target ractors.
- #
- def empty?
- __builtin_ractor_selector_empty_p
+ if ractors.delete Ractor.current
+ do_receive = true
+ else
+ do_receive = false
end
- # call-seq:
- # selector.wait(receive: false, yield_value: yield_value, move: false) -> [ractor or symbol, value]
- #
- # Waits Ractor events. It is lighter than Ractor.select() for many ractors.
- #
- # The simplest form is waiting for taking a value from one of
- # registerred ractors like that.
- #
- # selector = Ractor::Selector.new(r1, r2, r3)
- # r, v = selector.wait
- #
- # On this case, when r1, r2 or r3 is ready to take (yielding a value),
- # this method takes the value from the ready (yielded) ractor
- # and returns [the yielded ractor, the taking value].
- #
- # Note that if a take target ractor is closed, the ractor will be removed
- # automatically.
- #
- # If you also want to wait with receiving an object from other ractors,
- # you can specify receive: true keyword like:
- #
- # r, v = selector.wait receive: true
- #
- # On this case, wait for taking from r1, r2 or r3 and waiting for receving
- # a value from other ractors.
- # If it successes the receiving, it returns an array object [:receive, the received value].
- #
- # If you also want to wait with yielding a value, you can specify
- # :yield_value like:
- #
- # r, v = selector.wait yield_value: obj
- #
- # On this case wait for taking from r1, r2, or r3 and waiting for taking
- # yielding value (obj) by another ractor.
- # If antoher ractor takes the value (obj), it returns an array object [:yield, nil].
- #
- # You can specify a keyword parameter <tt>move: true</tt> like Ractor.yield(obj, move: true)
- #
- def wait receive: false, yield_value: yield_unspecified = true, move: false
- __builtin_ractor_selector_wait receive, !yield_unspecified, yield_value, move
- end
+ __builtin_ractor_select_internal ractors, do_receive, !yield_unspecified, yield_value, move
end
#