diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index f55b142581..9e90d95274 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -90,10 +90,10 @@ assert_equal 'ok', %q{ } # Ractor#send passes an object with copy to a Ractor -# and Ractor.recv in the Ractor block can receive the passed value. +# and Ractor.receive in the Ractor block can receive the passed value. assert_equal 'ok', %q{ r = Ractor.new do - msg = Ractor.recv + msg = Ractor.receive end r.send 'ok' r.take @@ -196,7 +196,7 @@ assert_equal 'ok', %q{ # Raise Ractor::ClosedError when try to send into a closed actor assert_equal 'ok', %q{ - r = Ractor.new { Ractor.recv } + r = Ractor.new { Ractor.receive } r.close begin @@ -212,7 +212,7 @@ assert_equal 'ok', %q{ assert_equal 'ok', %q{ r = Ractor.new do Ractor.yield 1 - Ractor.recv + Ractor.receive end r.close @@ -228,14 +228,14 @@ assert_equal 'ok', %q{ # Ractor.yield raises Ractor::ClosedError when outgoing port is closed. assert_equal 'ok', %q{ r = Ractor.new Ractor.current do |main| - Ractor.recv + Ractor.receive main << true Ractor.yield 1 end r.close_outgoing r << true - Ractor.recv + Ractor.receive begin r.take @@ -248,7 +248,7 @@ assert_equal 'ok', %q{ # Raise Ractor::ClosedError when try to send into a ractor with closed incoming port assert_equal 'ok', %q{ - r = Ractor.new { Ractor.recv } + r = Ractor.new { Ractor.receive } r.close_incoming begin @@ -275,7 +275,7 @@ assert_equal '[1, 2]', %q{ assert_equal 'ok', %q{ r = Ractor.new do Ractor.yield 1 - Ractor.recv + Ractor.receive end sleep 0.01 # wait for Ractor.yield in r @@ -292,7 +292,7 @@ assert_equal 'ok', %q{ # A ractor with closed outgoing port still can receive messages from incoming port assert_equal 'ok', %q{ r = Ractor.new do - Ractor.recv + Ractor.receive end r.close_outgoing @@ -305,11 +305,11 @@ assert_equal 'ok', %q{ end } -# multiple Ractors can recv (wait) from one Ractor +# multiple Ractors can receive (wait) from one Ractor assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{ pipe = Ractor.new do loop do - Ractor.yield Ractor.recv + Ractor.yield Ractor.receive end end @@ -330,7 +330,7 @@ assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{ }.sort } -# Ractor.select also support multiple take, recv and yiled +# Ractor.select also support multiple take, receive and yield assert_equal '[true, true, true]', %q{ RN = 10 CR = Ractor.current @@ -341,29 +341,29 @@ assert_equal '[true, true, true]', %q{ 'take' end } - recv = [] + received = [] take = [] - yiel = [] + yielded = [] until rs.empty? r, v = Ractor.select(CR, *rs, yield_value: 'yield') case r - when :recv - recv << v + when :receive + received << v when :yield - yiel << v + yielded << v else take << v rs.delete r end end - [recv.all?('sendyield'), yiel.all?(nil), take.all?('take')] + [received.all?('sendyield'), yielded.all?(nil), take.all?('take')] } # multiple Ractors can send to one Ractor assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{ pipe = Ractor.new do loop do - Ractor.yield Ractor.recv + Ractor.yield Ractor.receive end end @@ -378,7 +378,7 @@ assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{ }.sort } -# an exception in a Ractor will be re-raised at Ractor#recv +# an exception in a Ractor will be re-raised at Ractor#receive assert_equal '[RuntimeError, "ok", true]', %q{ r = Ractor.new do raise 'ok' # exception will be transferred receiver @@ -420,7 +420,7 @@ assert_equal 'no _dump_data is defined for class Thread', %q{ assert_equal "ok", %q{ echo_ractor = Ractor.new do loop do - v = Ractor.recv + v = Ractor.receive Ractor.yield v end end @@ -518,7 +518,7 @@ assert_equal [false, true, false].inspect, %q{ assert_equal 'hello world', %q{ # move r = Ractor.new do - obj = Ractor.recv + obj = Ractor.receive obj << ' world' end @@ -538,7 +538,7 @@ assert_equal 'hello world', %q{ # move example2: Array assert_equal '[0, 1]', %q{ r = Ractor.new do - ary = Ractor.recv + ary = Ractor.receive ary << 1 end @@ -746,7 +746,7 @@ assert_equal '[1000, 3]', %q{ assert_equal '[1, 4, 3, 2, 1]', %q{ counts = [] counts << Ractor.count - ractors = (1..3).map { Ractor.new { Ractor.recv } } + ractors = (1..3).map { Ractor.new { Ractor.receive } } counts << Ractor.count ractors[0].send('End 0').take diff --git a/doc/ractor.md b/doc/ractor.md index b0a8fc1d20..7867ca3f97 100644 --- a/doc/ractor.md +++ b/doc/ractor.md @@ -68,7 +68,7 @@ Ractor helps to write a thread-safe program, but we can make thread-unsafe progr * Some kind of shareable objects can introduce transactions (STM, for example). However, misusing transactions will generate inconsistent state. Without Ractor, we need to trace all of state-mutations to debug thread-safety issues. -With Ractor, you can concentrate to suspicious +With Ractor, you can concentrate to suspicious ## Creation and termination @@ -96,7 +96,7 @@ The Ractor execute given `expr` in a given block. Given block will be isolated from outer scope by `Proc#isolate`. ```ruby -# To prevent sharing unshareable objects between ractors, +# To prevent sharing unshareable objects between ractors, # block outer-variables, `self` and other information are isolated. # Given block will be isolated by `Proc#isolate` method. # `Proc#isolate` is called at Ractor creation timing (`Ractor.new` is called) @@ -133,7 +133,7 @@ r.take #=> 'ok' ```ruby # almost similar to the last example r = Ractor.new do - msg = Ractor.recv + msg = Ractor.receive msg end r.send 'ok' @@ -180,22 +180,22 @@ end Communication between Ractors is achieved by sending and receiving messages. * (1) Message sending/receiving - * (1-1) push type send/recv (sender knows receiver). similar to the Actor model. + * (1-1) push type send/receive (sender knows receiver). similar to the Actor model. * (1-2) pull type yield/take (receiver knows sender). * (2) Using shareable container objects (not implemented yet) Users can control blocking on (1), but should not control on (2) (only manage as critical section). -* (1-1) send/recv (push type) +* (1-1) send/receive (push type) * `Ractor#send(obj)` (`Ractor#<<(obj)` is an aliases) send a message to the Ractor's incoming port. Incoming port is connected to the infinite size incoming queue so `Ractor#send` will never block. - * `Ractor.recv` dequeue a message from its own incoming queue. If the incoming queue is empty, `Ractor.recv` calling will block. + * `Ractor.receive` dequeue a message from its own incoming queue. If the incoming queue is empty, `Ractor.receive` calling will block. * (1-2) yield/take (pull type) * `Ractor.yield(obj)` send an message to a Ractor which are calling `Ractor#take` via outgoing port . If no Ractors are waiting for it, the `Ractor.yield(obj)` will block. If multiple Ractors are waiting for `Ractor.yield(obj)`, only one Ractor can receive the message. * `Ractor#take` receives a message which is waiting by `Ractor.yield(obj)` method from the specified Ractor. If the Ractor does not call `Ractor.yield` yet, the `Ractor#take` call will block. -* `Ractor.select()` can wait for the success of `take`, `yield` and `recv`. +* `Ractor.select()` can wait for the success of `take`, `yield` and `receive`. * You can close the incoming port or outgoing port. * You can close then with `Ractor#close_incoming` and `Ractor#close_outgoing`. - * If the incoming port is closed for a Ractor, you can't `send` to the Ractor. If `Ractor.recv` is blocked for the closed incoming port, then it will raise an exception. + * If the incoming port is closed for a Ractor, you can't `send` to the Ractor. If `Ractor.receive` is blocked for the closed incoming port, then it will raise an exception. * If the outgoing port is closed for a Ractor, you can't call `Ractor#take` and `Ractor.yield` on the Ractor. If `Ractor#take` is blocked for the Ractor, then it will raise an exception. * When a Ractor is terminated, the Ractor's ports are closed. * There are 3 methods to send an object as a message @@ -216,11 +216,11 @@ Each Ractor has _incoming-port_ and _outgoing-port_. Incoming-port is connected r.send(obj) ->*->[incoming queue] Ractor.yield(obj) ->*-> r.take | | | | v | - | Ractor.recv | + | Ractor.receive | +-------------------------------------------+ -Connection example: r2.send obj on r1、Ractor.recv on r2 +Connection example: r2.send obj on r1、Ractor.receive on r2 +----+ +----+ * r1 |-----* r2 * +----+ +----+ @@ -245,7 +245,7 @@ Connection example: Ractor.yield(obj) on r1 and r2, ```ruby r = Ractor.new do - msg = Ractor.recv # Receive from r's incoming queue + msg = Ractor.receive # Receive from r's incoming queue msg # send back msg as block return value end r.send 'ok' # Send 'ok' to r's incoming port -> incoming queue @@ -253,10 +253,10 @@ Connection example: Ractor.yield(obj) on r1 and r2, ``` ```ruby - # Actual argument 'ok' for `Ractor.new()` will be send to created Ractor. + # Actual argument 'ok' for `Ractor.new()` will be send to created Ractor. r = Ractor.new 'ok' do |msg| # Values for formal parameters will be received from incoming queue. - # Similar to: msg = Ractor.recv + # Similar to: msg = Ractor.receive msg # Return value of the given block will be sent via outgoing port end @@ -304,7 +304,7 @@ Complex example: ```ruby pipe = Ractor.new do loop do - Ractor.yield Ractor.recv + Ractor.yield Ractor.receive end end @@ -333,7 +333,7 @@ Multiple Ractors can send to one Ractor. pipe = Ractor.new do loop do - Ractor.yield Ractor.recv + Ractor.yield Ractor.receive end end @@ -358,7 +358,7 @@ TODO: `select` syntax of go-language uses round-robin technique to make fair sch * `Ractor#close_incoming/outgoing` close incoming/outgoing ports (similar to `Queue#close`). * `Ractor#close_incoming` * `r.send(obj) ` where `r`'s incoming port is closed, will raise an exception. - * When the incoming queue is empty and incoming port is closed, `Ractor.recv` raise an exception. If the incoming queue is not empty, it dequeues an object. + * When the incoming queue is empty and incoming port is closed, `Ractor.receive` raise an exception. If the incoming queue is not empty, it dequeues an object. * `Ractor#close_outgoing` * `Ractor.yield` on a Ractor which closed the outgoing port, it will raise an exception. * `Ractor#take` for a Ractor which closed the outgoing port, it will raise an exception. If `Ractor#take` is blocking, it will raise an exception. @@ -411,7 +411,7 @@ r = Ractor.new obj do |msg| # return received msg's object_id msg.object_id end - + obj.object_id == r.take #=> false ``` @@ -438,7 +438,7 @@ If the source Ractor touches the moved object (for example, call the method like ```ruby # move with Ractor#send r = Ractor.new do - obj = Ractor.recv + obj = Ractor.receive obj << ' world' end @@ -468,7 +468,7 @@ end str = r.take begin - r.take + r.take rescue Ractor::RemoteError p str #=> "hello" end @@ -480,7 +480,7 @@ Now only `T_FILE`, `T_STRING` and `T_ARRAY` objects are supported. * `T_STRING` (`String`): support to send a huge string without copying (fast). * `T_ARRAY` (`Array'): support to send a huge Array without re-allocating the array's buffer. However, all of the referred objects from the array should be moved, so it is not so fast. -To achieve the access prohibition for moved objects, _class replacement_ technique is used to implement it. +To achieve the access prohibition for moved objects, _class replacement_ technique is used to implement it. ### Shareable objects @@ -500,7 +500,7 @@ Implementation: Now shareable objects (`RVALUE`) have `FL_SHAREABLE` flag. This ```ruby r = Ractor.new do - while v = Ractor.recv + while v = Ractor.receive Ractor.yield v end end @@ -659,19 +659,19 @@ RN = 1000 CR = Ractor.current r = Ractor.new do - p Ractor.recv + p Ractor.receive CR << :fin end RN.times{ r = Ractor.new r do |next_r| - next_r << Ractor.recv + next_r << Ractor.receive end } p :setup_ok r << 1 -p Ractor.recv +p Ractor.receive ``` ### Fork-join @@ -706,7 +706,7 @@ require 'prime' pipe = Ractor.new do loop do - Ractor.yield Ractor.recv + Ractor.yield Ractor.receive end end @@ -750,22 +750,22 @@ p r3.take #=> 'r1r2r3' ``` ```ruby -# pipeline with send/recv +# pipeline with send/receive r3 = Ractor.new Ractor.current do |cr| - cr.send Ractor.recv + 'r3' + cr.send Ractor.receive + 'r3' end r2 = Ractor.new r3 do |r3| - r3.send Ractor.recv + 'r2' + r3.send Ractor.receive + 'r2' end r1 = Ractor.new r2 do |r2| - r2.send Ractor.recv + 'r1' + r2.send Ractor.receive + 'r1' end r1 << 'r0' -p Ractor.recv #=> "r0r1r2r3" +p Ractor.receive #=> "r0r1r2r3" ``` ### Supervise @@ -776,12 +776,12 @@ p Ractor.recv #=> "r0r1r2r3" r = Ractor.current (1..10).map{|i| r = Ractor.new r, i do |r, i| - r.send Ractor.recv + "r#{i}" + r.send Ractor.receive + "r#{i}" end } r.send "r0" -p Ractor.recv #=> "r0r10r9r8r7r6r5r4r3r2r1" +p Ractor.receive #=> "r0r10r9r8r7r6r5r4r3r2r1" ``` ```ruby @@ -791,7 +791,7 @@ r = Ractor.current rs = (1..10).map{|i| r = Ractor.new r, i do |r, i| loop do - msg = Ractor.recv + msg = Ractor.receive raise if /e/ =~ msg r.send msg + "r#{i}" end @@ -799,10 +799,10 @@ rs = (1..10).map{|i| } r.send "r0" -p Ractor.recv #=> "r0r10r9r8r7r6r5r4r3r2r1" +p Ractor.receive #=> "r0r10r9r8r7r6r5r4r3r2r1" r.send "r0" -p Ractor.select(*rs, Ractor.current) #=> [:recv, "r0r10r9r8r7r6r5r4r3r2r1"] -[:recv, "r0r10r9r8r7r6r5r4r3r2r1"] +p Ractor.select(*rs, Ractor.current) #=> [:receive, "r0r10r9r8r7r6r5r4r3r2r1"] +[:receive, "r0r10r9r8r7r6r5r4r3r2r1"] r.send "e0" p Ractor.select(*rs, Ractor.current) #=> @@ -826,7 +826,7 @@ r = Ractor.current rs = (1..10).map{|i| r = Ractor.new r, i do |r, i| loop do - msg = Ractor.recv + msg = Ractor.receive raise if /e/ =~ msg r.send msg + "r#{i}" end @@ -834,10 +834,10 @@ rs = (1..10).map{|i| } r.send "r0" -p Ractor.recv #=> "r0r10r9r8r7r6r5r4r3r2r1" +p Ractor.receive #=> "r0r10r9r8r7r6r5r4r3r2r1" r.send "r0" p Ractor.select(*rs, Ractor.current) -[:recv, "r0r10r9r8r7r6r5r4r3r2r1"] +[:receive, "r0r10r9r8r7r6r5r4r3r2r1"] msg = 'e0' begin r.send msg @@ -857,7 +857,7 @@ end def make_ractor r, i Ractor.new r, i do |r, i| loop do - msg = Ractor.recv + msg = Ractor.receive raise if /e/ =~ msg r.send msg + "r#{i}" end @@ -879,5 +879,5 @@ rescue Ractor::RemoteError retry end -#=> [:recv, "x0r9r9r8r7r6r5r4r3r2r1"] +#=> [:receive, "x0r9r9r8r7r6r5r4r3r2r1"] ``` diff --git a/ractor.c b/ractor.c index 1ab4f37681..a8b12c7351 100644 --- a/ractor.c +++ b/ractor.c @@ -503,7 +503,7 @@ ractor_copy_setup(struct rb_ractor_basket *b, VALUE obj) } static VALUE -ractor_try_recv(rb_execution_context_t *ec, rb_ractor_t *r) +ractor_try_receive(rb_execution_context_t *ec, rb_ractor_t *r) { struct rb_ractor_queue *rq = &r->incoming_queue; struct rb_ractor_basket basket; @@ -553,13 +553,13 @@ wait_status_str(enum ractor_wait_status wait_status) { switch ((int)wait_status) { case wait_none: return "none"; - case wait_recving: return "recving"; + case wait_receiving: return "receiving"; case wait_taking: return "taking"; case wait_yielding: return "yielding"; - case wait_recving|wait_taking: return "recving|taking"; - case wait_recving|wait_yielding: return "recving|yielding"; + case wait_receiving|wait_taking: return "receiving|taking"; + case wait_receiving|wait_yielding: return "receiving|yielding"; case wait_taking|wait_yielding: return "taking|yielding"; - case wait_recving|wait_taking|wait_yielding: return "recving|taking|yielding"; + case wait_receiving|wait_taking|wait_yielding: return "receiving|taking|yielding"; } rb_bug("unrechable"); } @@ -715,18 +715,18 @@ ractor_waiting_list_shift(rb_ractor_t *r, struct rb_ractor_waiting_list *wl) } static VALUE -ractor_recv(rb_execution_context_t *ec, rb_ractor_t *r) +ractor_receive(rb_execution_context_t *ec, rb_ractor_t *r) { VM_ASSERT(r == rb_ec_ractor_ptr(ec)); VALUE v; - while ((v = ractor_try_recv(ec, r)) == Qundef) { + while ((v = ractor_try_receive(ec, r)) == Qundef) { RACTOR_LOCK(r); { if (ractor_queue_empty_p(r, &r->incoming_queue)) { VM_ASSERT(r->wait.status == wait_none); VM_ASSERT(r->wait.wakeup_status == wakeup_none); - r->wait.status = wait_recving; + r->wait.status = wait_receiving; ractor_sleep(ec, r); @@ -752,7 +752,7 @@ ractor_send_basket(rb_execution_context_t *ec, rb_ractor_t *r, struct rb_ractor_ } else { ractor_queue_enq(r, rq, b); - if (ractor_wakeup(r, wait_recving, wakeup_by_send)) { + if (ractor_wakeup(r, wait_receiving, wakeup_by_send)) { RUBY_DEBUG_LOG("wakeup", 0); } } @@ -890,7 +890,7 @@ ractor_select(rb_execution_context_t *ec, const VALUE *rs, int alen, VALUE yield struct ractor_select_action { enum ractor_select_action_type { ractor_select_action_take, - ractor_select_action_recv, + ractor_select_action_receive, ractor_select_action_yield, } type; VALUE v; @@ -906,9 +906,9 @@ ractor_select(rb_execution_context_t *ec, const VALUE *rs, int alen, VALUE yield VALUE v = rs[i]; if (v == crv) { - actions[i].type = ractor_select_action_recv; + actions[i].type = ractor_select_action_receive; actions[i].v = Qnil; - wait_status |= wait_recving; + wait_status |= wait_receiving; } else if (rb_ractor_p(v)) { actions[i].type = ractor_select_action_take; @@ -949,10 +949,10 @@ ractor_select(rb_execution_context_t *ec, const VALUE *rs, int alen, VALUE yield goto cleanup; } break; - case ractor_select_action_recv: - v = ractor_try_recv(ec, cr); + case ractor_select_action_receive: + v = ractor_try_receive(ec, cr); if (v != Qundef) { - *ret_r = ID2SYM(rb_intern("recv")); + *ret_r = ID2SYM(rb_intern("receive")); ret = v; goto cleanup; } @@ -988,7 +988,7 @@ ractor_select(rb_execution_context_t *ec, const VALUE *rs, int alen, VALUE yield ractor_register_taking(r, cr); break; case ractor_select_action_yield: - case ractor_select_action_recv: + case ractor_select_action_receive: break; } } @@ -1009,7 +1009,7 @@ ractor_select(rb_execution_context_t *ec, const VALUE *rs, int alen, VALUE yield goto skip_sleep; } break; - case ractor_select_action_recv: + case ractor_select_action_receive: if (cr->incoming_queue.cnt > 0) { RUBY_DEBUG_LOG("wakeup_none, but incoming_queue has %u messages", cr->incoming_queue.cnt); cr->wait.wakeup_status = wakeup_by_retry; @@ -1052,7 +1052,7 @@ ractor_select(rb_execution_context_t *ec, const VALUE *rs, int alen, VALUE yield r = RACTOR_PTR(actions[i].v); ractor_waiting_list_del(r, &r->taking_ractors, cr); break; - case ractor_select_action_recv: + case ractor_select_action_receive: case ractor_select_action_yield: break; } @@ -1072,7 +1072,7 @@ ractor_select(rb_execution_context_t *ec, const VALUE *rs, int alen, VALUE yield break; case wakeup_by_send: // OK. - // retry loop and try_recv will succss. + // retry loop and try_receive will succss. break; case wakeup_by_yield: // take was succeeded! @@ -1145,7 +1145,7 @@ ractor_close_incoming(rb_execution_context_t *ec, rb_ractor_t *r) if (!r->incoming_port_closed) { prev = Qfalse; r->incoming_port_closed = true; - if (ractor_wakeup(r, wait_recving, wakeup_by_close)) { + if (ractor_wakeup(r, wait_receiving, wakeup_by_close)) { VM_ASSERT(r->incoming_queue.cnt == 0); RUBY_DEBUG_LOG("cancel receiving", 0); } @@ -1442,10 +1442,10 @@ rb_ractor_atexit_exception(rb_execution_context_t *ec) } void -rb_ractor_recv_parameters(rb_execution_context_t *ec, rb_ractor_t *r, int len, VALUE *ptr) +rb_ractor_receive_parameters(rb_execution_context_t *ec, rb_ractor_t *r, int len, VALUE *ptr) { for (int i=0; i 1 - # Ractor.recv # recv via r's mailbox => 2 + # Ractor.receive # receive via r's mailbox => 1 + # Ractor.receive # receive via r's mailbox => 2 # Ractor.yield 3 # yield a message (3) and wait for taking by another ractor. # 'ok' # the return value will be yielded. # # and r's incoming/outgoing ports are closed automatically. # end # r.send 1 # send a message (1) into r's mailbox. # r << 2 # << is an alias of `send`. - # p r.take # take a message from r's outgoing port #=> 3 - # p r.take # => 'ok' + # p r.take # take a message from r's outgoing port => 3 + # p r.take # => 'ok' # p r.take # raise Ractor::ClosedError # # other options: # name: Ractor's name # - def self.new *args, name: nil, &block + def self.new(*args, name: nil, &block) b = block # TODO: builtin bug raise ArgumentError, "must be called with a block" unless block loc = caller_locations(1, 1).first @@ -59,18 +59,18 @@ class Ractor # # r, obj = Ractor.select(r1, r2, Ractor.current) # #=> wait for taking from r1 or r2 - # # or recv from incoming queue - # # If recv is succeed, then obj is received value - # # and r is :recv (Ractor.current) + # # or receive from incoming queue + # # If receive is succeed, then obj is received value + # # and r is :receive (Ractor.current) # # r, obj = Ractor.select(r1, r2, Ractor.current, yield_value: obj) # #=> wait for taking from r1 or r2 - # # or recv from incoming queue + # # or receive from incoming queue # # or yield (Ractor.yield) obj # # If yield is succeed, then obj is nil # # and r is :yield # - def self.select *ractors, yield_value: yield_unspecified = true, move: false + def self.select(*ractors, yield_value: yield_unspecified = true, move: false) __builtin_cstmt! %q{ const VALUE *rs = RARRAY_CONST_PTR_TRANSIENT(ractors); VALUE rv; @@ -82,34 +82,40 @@ class Ractor end # Receive an incoming message from Ractor's incoming queue. - def self.recv + def self.receive __builtin_cexpr! %q{ - ractor_recv(ec, rb_ec_ractor_ptr(ec)) + ractor_receive(ec, rb_ec_ractor_ptr(ec)) } end - private def recv + class << self + alias recv receive + end + + private def receive __builtin_cexpr! %q{ // TODO: check current actor - ractor_recv(ec, RACTOR_PTR(self)) + ractor_receive(ec, RACTOR_PTR(self)) } end + alias recv receive # Send a message to a Ractor's incoming queue. # # # Example: # r = Ractor.new do - # p Ractor.recv #=> 'ok' + # p Ractor.receive #=> 'ok' # end # r.send 'ok' # send to r's incoming queue. - def send obj, move: false + def send(obj, move: false) __builtin_cexpr! %q{ ractor_send(ec, RACTOR_PTR(self), obj, move) } end + alias << send # yield a message to the ractor's outgoing port. - def self.yield obj, move: false + def self.yield(obj, move: false) __builtin_cexpr! %q{ ractor_yield(ec, rb_ec_ractor_ptr(ec), obj, move) } @@ -126,8 +132,6 @@ class Ractor } end - alias << send - def inspect loc = __builtin_cexpr! %q{ RACTOR_PTR(self)->loc } name = __builtin_cexpr! %q{ RACTOR_PTR(self)->name } diff --git a/thread.c b/thread.c index 6cc0a9227e..40c84f8e55 100644 --- a/thread.c +++ b/thread.c @@ -720,7 +720,7 @@ thread_do_start_proc(rb_thread_t *th) VM_ASSERT(FIXNUM_P(args)); args_len = FIX2INT(args); args_ptr = ALLOCA_N(VALUE, args_len); - rb_ractor_recv_parameters(th->ec, th->ractor, args_len, (VALUE *)args_ptr); + rb_ractor_receive_parameters(th->ec, th->ractor, args_len, (VALUE *)args_ptr); vm_check_ints_blocking(th->ec); // kick thread