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;
|
||
-
|