aboutsummaryrefslogtreecommitdiffstats
path: root/variable.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-12-20 03:23:41 +0900
committerKoichi Sasada <ko1@atdot.net>2020-12-20 11:46:13 +0900
commitf70b894b8829c064e39646c9b5f6d304d13bb16d (patch)
tree21f6888a64bd4697d12eba2baa8b222ad9f17fe6 /variable.c
parent648bbfcc65ad28841db2206513375dd88f064c52 (diff)
downloadruby-f70b894b8829c064e39646c9b5f6d304d13bb16d.tar.gz
sync RCLASS_CONST_TBL()
RCLASS_CONST_TBL() is shared resource so we need to sync with other ractors.
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c91
1 files changed, 62 insertions, 29 deletions
diff --git a/variable.c b/variable.c
index 3b1462b9de..b780446f19 100644
--- a/variable.c
+++ b/variable.c
@@ -2349,7 +2349,13 @@ autoload_const_set(struct autoload_const *ac)
VALUE klass = ac->mod;
ID id = ac->id;
check_before_mod_set(klass, id, ac->value, "constant");
- const_tbl_update(ac);
+
+ RB_VM_LOCK_ENTER();
+ {
+ const_tbl_update(ac);
+ }
+ RB_VM_LOCK_LEAVE();
+
return 0; /* ignored */
}
@@ -2782,8 +2788,13 @@ rb_local_constants(VALUE mod)
if (!tbl) return rb_ary_new2(0);
- ary = rb_ary_new2(rb_id_table_size(tbl));
- rb_id_table_foreach(tbl, rb_local_constants_i, (void *)ary);
+ RB_VM_LOCK_ENTER();
+ {
+ ary = rb_ary_new2(rb_id_table_size(tbl));
+ rb_id_table_foreach(tbl, rb_local_constants_i, (void *)ary);
+ }
+ RB_VM_LOCK_LEAVE();
+
return ary;
}
@@ -2795,7 +2806,11 @@ rb_mod_const_at(VALUE mod, void *data)
tbl = st_init_numtable();
}
if (RCLASS_CONST_TBL(mod)) {
- rb_id_table_foreach(RCLASS_CONST_TBL(mod), sv_i, tbl);
+ RB_VM_LOCK_ENTER();
+ {
+ rb_id_table_foreach(RCLASS_CONST_TBL(mod), sv_i, tbl);
+ }
+ RB_VM_LOCK_LEAVE();
}
return tbl;
}
@@ -2971,20 +2986,24 @@ static void
set_namespace_path(VALUE named_namespace, VALUE namespace_path)
{
struct rb_id_table *const_table = RCLASS_CONST_TBL(named_namespace);
- if (!RCLASS_IV_TBL(named_namespace)) {
- RCLASS_IV_TBL(named_namespace) = st_init_numtable();
- }
- rb_class_ivar_set(named_namespace, classpath, namespace_path);
- if (const_table) {
- rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path);
+
+ RB_VM_LOCK_ENTER();
+ {
+ if (!RCLASS_IV_TBL(named_namespace)) {
+ RCLASS_IV_TBL(named_namespace) = st_init_numtable();
+ }
+ rb_class_ivar_set(named_namespace, classpath, namespace_path);
+ if (const_table) {
+ rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path);
+ }
}
+ RB_VM_LOCK_LEAVE();
}
void
rb_const_set(VALUE klass, ID id, VALUE val)
{
rb_const_entry_t *ce;
- struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
@@ -2996,21 +3015,28 @@ rb_const_set(VALUE klass, ID id, VALUE val)
}
check_before_mod_set(klass, id, val, "constant");
- if (!tbl) {
- RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
- rb_clear_constant_cache();
- ce = ZALLOC(rb_const_entry_t);
- rb_id_table_insert(tbl, id, (VALUE)ce);
- setup_const_entry(ce, klass, val, CONST_PUBLIC);
- }
- else {
- struct autoload_const ac = {
- .mod = klass, .id = id,
- .value = val, .flag = CONST_PUBLIC,
- /* fill the rest with 0 */
- };
- const_tbl_update(&ac);
+
+ RB_VM_LOCK_ENTER();
+ {
+ struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
+ if (!tbl) {
+ RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
+ rb_clear_constant_cache();
+ ce = ZALLOC(rb_const_entry_t);
+ rb_id_table_insert(tbl, id, (VALUE)ce);
+ setup_const_entry(ce, klass, val, CONST_PUBLIC);
+ }
+ else {
+ struct autoload_const ac = {
+ .mod = klass, .id = id,
+ .value = val, .flag = CONST_PUBLIC,
+ /* fill the rest with 0 */
+ };
+ const_tbl_update(&ac);
+ }
}
+ RB_VM_LOCK_LEAVE();
+
/*
* Resolve and cache class name immediately to resolve ambiguity
* and avoid order-dependency on const_tbl
@@ -3589,10 +3615,17 @@ MJIT_FUNC_EXPORTED rb_const_entry_t *
rb_const_lookup(VALUE klass, ID id)
{
struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
- VALUE val;
- if (tbl && rb_id_table_lookup(tbl, id, &val)) {
- return (rb_const_entry_t *)val;
+ if (tbl) {
+ VALUE val;
+ bool r;
+ RB_VM_LOCK_ENTER();
+ {
+ r = rb_id_table_lookup(tbl, id, &val);
+ }
+ RB_VM_LOCK_LEAVE();
+
+ if (r) return (rb_const_entry_t *)val;
}
- return 0;
+ return NULL;
}