summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-09-10 16:51:24 +0900
committerKoichi Sasada <ko1@atdot.net>2020-09-10 18:44:02 +0900
commitea78960ee5cb78c6aaaaa7091b85066a011c51e9 (patch)
tree852818640660914c73ac53208d784e9f04a4cc55 /vm_method.c
parent475c8701d74ebebefb2f53052cde1a5effb4cb81 (diff)
sync callable_method_entry()
callable_method_entry() read/write method table structures so that this function should be synchronized between Ractors.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3529
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/vm_method.c b/vm_method.c
index 58516b9ddd..0428ae6380 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -1013,6 +1013,8 @@ complemented_callable_method_entry(VALUE klass, ID id)
static const rb_callable_method_entry_t *
cached_callable_method_entry(VALUE klass, ID mid)
{
+ ASSERT_vm_locking();
+
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
struct rb_class_cc_entries *ccs;
@@ -1035,6 +1037,8 @@ cached_callable_method_entry(VALUE klass, ID mid)
static void
cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_t *cme)
{
+ ASSERT_vm_locking();
+
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
struct rb_class_cc_entries *ccs;
@@ -1054,19 +1058,25 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_
static const rb_callable_method_entry_t *
callable_method_entry(VALUE klass, ID mid, VALUE *defined_class_ptr)
{
+ const rb_callable_method_entry_t *cme;
+
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS));
- const rb_callable_method_entry_t *cme = cached_callable_method_entry(klass, mid);
+ RB_VM_LOCK_ENTER();
+ {
+ cme = cached_callable_method_entry(klass, mid);
- if (cme) {
- if (defined_class_ptr != NULL) *defined_class_ptr = cme->defined_class;
- }
- else {
- VALUE defined_class;
- rb_method_entry_t *me = search_method_protect(klass, mid, &defined_class);
- if (defined_class_ptr) *defined_class_ptr = defined_class;
- cme = prepare_callable_method_entry(defined_class, mid, me, TRUE);
- if (cme) cache_callable_method_entry(klass, mid, cme);
+ if (cme) {
+ if (defined_class_ptr != NULL) *defined_class_ptr = cme->defined_class;
+ }
+ else {
+ VALUE defined_class;
+ rb_method_entry_t *me = search_method_protect(klass, mid, &defined_class);
+ if (defined_class_ptr) *defined_class_ptr = defined_class;
+ cme = prepare_callable_method_entry(defined_class, mid, me, TRUE);
+ if (cme) cache_callable_method_entry(klass, mid, cme);
+ }
}
+ RB_VM_LOCK_LEAVE();
return cme;
}