Bug #15263 ยป 0001-vm_trace.c-postponed_job_register-only-hit-main-thre.patch
| cont.c | ||
|---|---|---|
|
{
|
||
|
rb_execution_context_t *ec = &fib->cont.saved_ec;
|
||
|
ruby_current_execution_context_ptr = th->ec = ec;
|
||
|
if (th->vm->main_thread == th) {
|
||
|
/*
|
||
|
* Other thread may set interrupt on previous th->ec at any time;
|
||
|
* ensure we do not delay (or lose) the trap interrupt handling.
|
||
|
*/
|
||
|
rb_atomic_t old_fl, new_fl;
|
||
|
rb_execution_context_t *prev_ec = ruby_current_execution_context_ptr;
|
||
|
/*
|
||
|
* timer-thread may set trap interrupt on previous th->ec at any time;
|
||
|
* ensure we do not delay (or lose) the trap interrupt handling.
|
||
|
*/
|
||
|
if (th->vm->main_thread == th && rb_signal_buff_size() > 0) {
|
||
|
RUBY_VM_SET_TRAP_INTERRUPT(ec);
|
||
|
ruby_current_execution_context_ptr = th->ec = ec;
|
||
|
old_fl = ATOMIC_EXCHANGE(prev_ec->interrupt_flag, 0);
|
||
|
/* migrate interrupts from the previous EC to the current EC */
|
||
|
new_fl = old_fl & (TIMER_INTERRUPT_MASK |
|
||
|
POSTPONED_JOB_INTERRUPT_MASK |
|
||
|
TRAP_INTERRUPT_MASK);
|
||
|
if (new_fl) ATOMIC_OR(ec->interrupt_flag, new_fl);
|
||
|
/* Pending-interrupts stay with the previous EC */
|
||
|
old_fl &= PENDING_INTERRUPT_MASK;
|
||
|
if (old_fl) ATOMIC_OR(prev_ec->interrupt_flag, old_fl);
|
||
|
}
|
||
|
else {
|
||
|
ruby_current_execution_context_ptr = th->ec = ec;
|
||
|
}
|
||
|
VM_ASSERT(ec->fiber_ptr->cont.self == 0 || ec->vm_stack != NULL);
|
||
| vm_trace.c | ||
|---|---|---|
|
/* Async-signal-safe */
|
||
|
static enum postponed_job_register_result
|
||
|
postponed_job_register(rb_execution_context_t *ec, rb_vm_t *vm,
|
||
|
postponed_job_register(rb_vm_t *vm,
|
||
|
unsigned int flags, rb_postponed_job_func_t func, void *data, int max, int expected_index)
|
||
|
{
|
||
|
rb_postponed_job_t *pjob;
|
||
| ... | ... | |
|
pjob->func = func;
|
||
|
pjob->data = data;
|
||
|
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(ec);
|
||
|
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(vm->main_thread->ec);
|
||
|
return PJRR_SUCCESS;
|
||
|
}
|
||
| ... | ... | |
|
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();
|
||
|
begin:
|
||
|
switch (postponed_job_register(ec, vm, flags, func, data, MAX_POSTPONED_JOB, vm->postponed_job_index)) {
|
||
|
switch (postponed_job_register(vm, flags, func, data, MAX_POSTPONED_JOB, vm->postponed_job_index)) {
|
||
|
case PJRR_SUCCESS : return 1;
|
||
|
case PJRR_FULL : return 0;
|
||
|
case PJRR_INTERRUPTED: goto begin;
|
||
| ... | ... | |
|
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_postponed_job_t *pjob;
|
||
|
int i, index;
|
||
| ... | ... | |
|
for (i=0; i<index; i++) {
|
||
|
pjob = &vm->postponed_job_buffer[i];
|
||
|
if (pjob->func == func) {
|
||
|
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(ec);
|
||
|
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(vm->main_thread->ec);
|
||
|
return 2;
|
||
|
}
|
||
|
}
|
||
|
switch (postponed_job_register(ec, vm, flags, func, data, MAX_POSTPONED_JOB + MAX_POSTPONED_JOB_SPECIAL_ADDITION, index)) {
|
||
|
switch (postponed_job_register(vm, flags, func, data, MAX_POSTPONED_JOB + MAX_POSTPONED_JOB_SPECIAL_ADDITION, index)) {
|
||
|
case PJRR_SUCCESS : return 1;
|
||
|
case PJRR_FULL : return 0;
|
||
|
case PJRR_INTERRUPTED: goto begin;
|
||
|
-
|
||