8000 Use a T_DATA for cross_ractor_require · ruby/ruby@cb5120c · GitHub
[go: up one dir, main page]

Skip to content

Commit cb5120c

Browse files
Use a T_DATA for cross_ractor_require
[Bug #21090] The struct was previously allocated on the stack, which could be freed if the Thread is terminated. Moving this to a T_DATA on the heap should mean this is no longer an issue. 1000.times { Ractor.new { th = Thread.new { require "rbconfig" }; Thread.pass }.take } Co-authored-by: Luke Gruber <luke.gruber@shopify.com>
1 parent 1c0ef71 commit cb5120c

File tree

1 file changed

+68
-35
lines changed

1 file changed

+68
-35
lines changed

ractor.c

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,28 @@ struct cross_ractor_require {
22372237
ID name;
22382238
};
22392239

2240+
static void
2241+
cross_ractor_require_mark(void *ptr)
2242+
{
2243+
struct cross_ractor_require *crr = (struct cross_ractor_require *)ptr;
2244+
rb_gc_mark(crr->port);
2245+
rb_gc_mark(crr->result);
2246+
rb_gc_mark(crr->exception);
2247+
rb_gc_mark(crr->feature);
2248+
rb_gc_mark(crr->module);
2249+
}
2250+
2251+
static const rb_data_type_t cross_ractor_require_data_type = {
2252+
"ractor/cross_ractor_require",
2253+
{
2254+
cross_ractor_require_mark,
2255+
RUBY_DEFAULT_FREE,
2256+
NULL, // memsize
2257+
NULL, // compact
2258+
},
2259+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
2260+
};
2261+
22402262
static VALUE
22412263
require_body(VALUE data)
22422264
{
@@ -2283,8 +2305,11 @@ require_result_copy_resuce(VALUE data, VALUE errinfo)
22832305
}
22842306

22852307
static VALUE
2286-
ractor_require_protect(struct cross_ractor_require *crr, VALUE (*func)(VALUE))
2308+
ractor_require_protect(VALUE crr_obj, VALUE (*func)(VALUE))
22872309
{
2310+
struct cross_ractor_require *crr;
2311+
TypedData_Get_Struct(crr_obj, struct cross_ractor_require, &cross_ractor_require_data_type, crr);
2312+
22882313
// catch any error
22892314
rb_rescue2(func, (VALUE)crr,
22902315
require_rescue, (VALUE)crr, rb_eException, 0);
@@ -2293,43 +2318,48 @@ ractor_require_protect(struct cross_ractor_require *crr, VALUE (*func)(VALUE))
22932318
require_result_copy_resuce, (VALUE)crr, rb_eException, 0);
22942319

22952320
ractor_port_send(GET_EC(), crr->port, Qtrue, Qfalse);
2321+
RB_GC_GUARD(crr_obj);
22962322
return Qnil;
22972323
}
22982324

22992325
static VALUE
2300-
ractor_require_func(void *data)
2326+
ractor_require_func(void *crr_obj)
23012327
{
2302-
struct cross_ractor_require *crr = (struct cross_ractor_require *)data;
2303-
return ractor_require_protect(crr, require_body);
2328+
return ractor_require_protect((VALUE)crr_obj, require_body);
23042329
}
23052330

23062331
VALUE
23072332
rb_ractor_require(VALUE feature)
23082333
{
2334+
struct cross_ractor_require *crr;
2335+
VALUE crr_obj = TypedData_Make_Struct(0, struct cross_ractor_require, &cross_ractor_require_data_type, crr);
2336+
23092337
// TODO: make feature shareable
2310-
struct cross_ractor_require crr = {
2311-
.feature = feature, // TODO: ractor
2312-
.port = ractor_port_new(GET_RACTOR()),
2313-
.result = Qundef,
2314-
.exception = Qundef,
2315-
};
2338+
crr->feature = feature;
2339+
crr->port = ractor_port_new(GET_RACTOR());
2340+
crr->result = Qundef;
2341+
crr->exception = Qundef;
23162342

23172343
rb_execution_context_t *ec = GET_EC();
23182344
rb_ractor_t *main_r = GET_VM()->ractor.main_ractor;
2319-
rb_ractor_interrupt_exec(main_r, ractor_require_func, &crr, 0);
2345+
rb_ractor_interrupt_exec(main_r, ractor_require_func, (void *)crr_obj, rb_interrupt_exec_flag_value_data);
23202346

23212347
// wait for require done
2322-
ractor_port_receive(ec, crr.port);
2323-
ractor_port_close(ec, crr.port);
2348+
ractor_port_receive(ec, crr->port);
2349+
ractor_port_close(ec, crr->port);
23242350

2325-
if (crr.exception != Qundef) {
2326-
ractor_reset_belonging(crr.exception);
2327-
rb_exc_raise(crr.exception);
2351+
VALUE exc = crr->exception;
2352+
VALUE result = crr->result;
2353+
RB_GC_GUARD(crr_obj);
2354+
2355+
if (exc != Qundef) {
2356+
ractor_reset_belonging(exc);
2357+
rb_exc_raise(exc);
23282358
}
23292359
else {
2330-
RUBY_ASSERT(crr.result != Qundef);
2331-
ractor_reset_belonging(crr.result);
2332-
return crr.r 6D4E esult;
2360+
RUBY_ASSERT(result != Qundef);
2361+
ractor_reset_belonging(result);
2362+
return result;
23332363
}
23342364
}
23352365

@@ -2348,36 +2378,39 @@ autoload_load_body(VALUE data)
23482378
}
23492379

23502380
static VALUE
2351-
ractor_autoload_load_func(void *data)
2381+
ractor_autoload_load_func(void *crr_obj)
23522382
{
2353-
struct cross_ractor_require *crr = (struct cross_ractor_require *)data;
2354-
return ractor_require_protect(crr, autoload_load_body);
2383+
return ractor_require_protect((VALUE)crr_obj, autoload_load_body);
23552384
}
23562385

23572386
VALUE
23582387
rb_ractor_autoload_load(VALUE module, ID name)
23592388
{
2360-
struct cross_ractor_require crr = {
2361-
.module = module,
2362-
.name = name,
2363-
.port = ractor_port_new(GET_RACTOR()),
2364-
.result = Qundef,
2365-
.exception = Qundef,
2366-
};
2389+
struct cross_ractor_require *crr;
2390+
VALUE crr_obj = TypedData_Make_Struct(0, struct cross_ractor_require, &cross_ractor_require_data_type, crr);
2391+
crr->module = module;
2392+
crr->name = name;
2393+
crr->port = ractor_port_new(GET_RACTOR());
2394+
crr->result = Qundef;
2395+
crr->exception = Qundef;
23672396

23682397
rb_execution_context_t *ec = GET_EC();
23692398
rb_ractor_t *main_r = GET_VM()->ractor.main_ractor;
2370-
rb_ractor_interrupt_exec(main_r, ractor_autoload_load_func, &crr, 0);
2399+
rb_ractor_interrupt_exec(main_r, ractor_autoload_load_func, (void *)crr_obj, rb_interrupt_exec_flag_value_data);
23712400

23722401
// wait for require done
2373-
ractor_port_receive(ec, crr.port);
2374-
ractor_port_close(ec, crr.port);
2402+
ractor_port_receive(ec, crr->port);
2403+
ractor_port_close(ec, crr->port);
2404+
2405+
VALUE exc = crr->exception;
2406+
VALUE result = crr->result;
2407+
RB_GC_GUARD(crr_obj);
23752408

2376-
if (crr.exception != Qundef) {
2377-
rb_exc_raise(crr.exception);
2409+
if (exc != Qundef) {
2410+
rb_exc_raise(exc);
23782411
}
23792412
else {
2380-
return crr.result;
2413+
return result;
23812414
}
23822415
}
23832416

0 commit comments

Comments
 (0)
0