1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

add Ractor#[]/#[]= for ractor local storage

This API is similar to plain old Thread#[]/Fiber#[] interface
with symbol key.
This commit is contained in:
Koichi Sasada 2020-12-22 01:55:15 +09:00
parent 8f2031a067
commit 35471a9487
Notes: git 2020-12-22 05:26:56 +09:00
4 changed files with 71 additions and 0 deletions

View file

@ -1245,6 +1245,20 @@ assert_equal '[:ok, :ok]', %q{
end
}
# Ractor-local storage
assert_equal '[nil, "b", "a"]', %q{
ans = []
Ractor.current[:key] = 'a'
r = Ractor.new{
Ractor.yield self[:key]
self[:key] = 'b'
self[:key]
}
ans << r.take
ans << r.take
ans << Ractor.current[:key]
}
###
### Synchronization tests
###

View file

@ -2928,6 +2928,13 @@ ractor_local_storage_mark_i(st_data_t key, st_data_t val, st_data_t dmy)
return ST_CONTINUE;
}
static enum rb_id_table_iterator_result
idkey_local_storage_mark_i(ID id, VALUE val, void *dmy)
{
rb_gc_mark(val);
return ID_TABLE_CONTINUE;
}
static void
ractor_local_storage_mark(rb_ractor_t *r)
{
@ -2943,6 +2950,10 @@ ractor_local_storage_mark(rb_ractor_t *r)
}
}
}
if (r->idkey_local_storage) {
rb_id_table_foreach(r->idkey_local_storage, idkey_local_storage_mark_i, NULL);
}
}
static int
@ -2960,6 +2971,10 @@ ractor_local_storage_free(rb_ractor_t *r)
st_foreach(r->local_storage, ractor_local_storage_free_i, 0);
st_free_table(r->local_storage);
}
if (r->idkey_local_storage) {
rb_id_table_free(r->idkey_local_storage);
}
}
static void
@ -3103,4 +3118,35 @@ rb_ractor_finish_marking(void)
}
}
static VALUE
ractor_local_value(rb_execution_context_t *ec, VALUE self, VALUE sym)
{
rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
ID id = rb_check_id(&sym);
struct rb_id_table *tbl = cr->idkey_local_storage;
VALUE val;
if (id && tbl && rb_id_table_lookup(tbl, id, &val)) {
rp(val);
return val;
}
else {
return Qnil;
}
}
static VALUE
ractor_local_value_set(rb_execution_context_t *ec, VALUE self, VALUE sym, VALUE val)
{
rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
ID id = SYM2ID(rb_to_symbol(sym));
struct rb_id_table *tbl = cr->idkey_local_storage;
if (tbl == NULL) {
tbl = cr->idkey_local_storage = rb_id_table_create(2);
}
rb_id_table_insert(tbl, id, val);
return val;
}
#include "ractor.rbinc"

View file

@ -758,4 +758,14 @@ class Ractor
}
end
end
# get a value from ractor-local storage
def [](sym)
Primitive.ractor_local_value(sym)
end
# set a value in ractor-local storage
def []=(sym, val)
Primitive.ractor_local_value_set(sym, val)
end
end

View file

@ -130,6 +130,7 @@ struct rb_ractor_struct {
// ractor local data
st_table *local_storage;
struct rb_id_table *idkey_local_storage;
VALUE r_stdin;
VALUE r_stdout;