Skip to content

Commit

Permalink
Use valid ec for postponed job.
Browse files Browse the repository at this point in the history
Postponed job can be registered from non-Ruby thread, which means
`ec` in TLS can be NULL. In this case, use main thread's `ec` instead.

See ruby#4108
and ruby#4336
  • Loading branch information
ko1 committed Nov 9, 2021
1 parent 3628616 commit 5680c38
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions vm_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1582,15 +1582,23 @@ postponed_job_register(rb_execution_context_t *ec, rb_vm_t *vm,
return PJRR_SUCCESS;
}

static rb_execution_context_t *
get_valid_ec(rb_vm_t *vm)
{
rb_execution_context_t *ec = GET_EC();
if (ec == NULL) ec = rb_vm_main_ractor_ec(vm);
return ec;
}

/*
* return 0 if job buffer is full
* Async-signal-safe
*/
int
rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void *data)
{
rb_execution_context_t *ec = GET_EC();
rb_vm_t *vm = rb_ec_vm_ptr(ec);
rb_vm_t *vm = GET_VM();
rb_execution_context_t *ec = get_valid_ec(vm);

begin:
switch (postponed_job_register(ec, vm, flags, func, data, MAX_POSTPONED_JOB, vm->postponed_job_index)) {
Expand All @@ -1608,8 +1616,8 @@ rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void
int
rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func, void *data)
{
rb_execution_context_t *ec = GET_EC();
rb_vm_t *vm = rb_ec_vm_ptr(ec);
rb_vm_t *vm = GET_VM();
rb_execution_context_t *ec = get_valid_ec(vm);
rb_postponed_job_t *pjob;
rb_atomic_t i, index;

Expand Down

0 comments on commit 5680c38

Please sign in to comment.