move rb_thread_t::interrupt_flag and mask
to rb_execution_context_t. * vm_core.h (rb_thread_t): move `rb_thread_t::interrupt_flag` and `rb_thread_t::interrupt_mask` to rb_execution_context_t. RUBY_VM_CHECK_INTS() accepts `ec` instead of `th`. * cont.c (rb_fiber_terminate): to propagate interrupt information, add new parameter `need_interrupt`. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60672 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5845bd6a71
commit
5dfdaa9299
30
cont.c
30
cont.c
@ -1389,7 +1389,7 @@ rb_fiber_new(VALUE (*func)(ANYARGS), VALUE obj)
|
|||||||
return fiber_init(fiber_alloc(rb_cFiber), rb_proc_new(func, obj));
|
return fiber_init(fiber_alloc(rb_cFiber), rb_proc_new(func, obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rb_fiber_terminate(rb_fiber_t *fib);
|
static void rb_fiber_terminate(rb_fiber_t *fib, int need_interrupt);
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_fiber_start(void)
|
rb_fiber_start(void)
|
||||||
@ -1398,6 +1398,7 @@ rb_fiber_start(void)
|
|||||||
rb_fiber_t *fib = th->ec->fiber_ptr;
|
rb_fiber_t *fib = th->ec->fiber_ptr;
|
||||||
rb_proc_t *proc;
|
rb_proc_t *proc;
|
||||||
enum ruby_tag_type state;
|
enum ruby_tag_type state;
|
||||||
|
int need_interrupt = TRUE;
|
||||||
|
|
||||||
VM_ASSERT(th->ec == ruby_current_execution_context_ptr);
|
VM_ASSERT(th->ec == ruby_current_execution_context_ptr);
|
||||||
VM_ASSERT(FIBER_RESUMED_P(fib));
|
VM_ASSERT(FIBER_RESUMED_P(fib));
|
||||||
@ -1420,20 +1421,22 @@ rb_fiber_start(void)
|
|||||||
EC_POP_TAG();
|
EC_POP_TAG();
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
|
VALUE err = th->ec->errinfo;
|
||||||
VM_ASSERT(FIBER_RESUMED_P(fib));
|
VM_ASSERT(FIBER_RESUMED_P(fib));
|
||||||
|
|
||||||
if (state == TAG_RAISE || state == TAG_FATAL) {
|
if (state == TAG_RAISE || state == TAG_FATAL) {
|
||||||
rb_threadptr_pending_interrupt_enque(th, th->ec->errinfo);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VALUE err = rb_vm_make_jump_tag_but_local_jump(state, th->ec->errinfo);
|
|
||||||
if (!NIL_P(err))
|
|
||||||
rb_threadptr_pending_interrupt_enque(th, err);
|
rb_threadptr_pending_interrupt_enque(th, err);
|
||||||
}
|
}
|
||||||
RUBY_VM_SET_INTERRUPT(th);
|
else {
|
||||||
|
err = rb_vm_make_jump_tag_but_local_jump(state, err);
|
||||||
|
if (!NIL_P(err)) {
|
||||||
|
rb_threadptr_pending_interrupt_enque(th, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
need_interrupt = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_fiber_terminate(fib);
|
rb_fiber_terminate(fib, need_interrupt);
|
||||||
VM_UNREACHABLE(rb_fiber_start);
|
VM_UNREACHABLE(rb_fiber_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1669,7 +1672,7 @@ fiber_switch(rb_fiber_t *fib, int argc, const VALUE *argv, int is_resume)
|
|||||||
cont->argc = argc;
|
cont->argc = argc;
|
||||||
cont->value = make_passing_arg(argc, argv);
|
cont->value = make_passing_arg(argc, argv);
|
||||||
value = fiber_store(fib, th);
|
value = fiber_store(fib, th);
|
||||||
RUBY_VM_CHECK_INTS(th);
|
RUBY_VM_CHECK_INTS(th->ec);
|
||||||
|
|
||||||
EXEC_EVENT_HOOK(th->ec, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, 0, Qnil);
|
EXEC_EVENT_HOOK(th->ec, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, 0, Qnil);
|
||||||
|
|
||||||
@ -1704,11 +1707,12 @@ rb_fiber_close(rb_fiber_t *fib)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rb_fiber_terminate(rb_fiber_t *fib)
|
rb_fiber_terminate(rb_fiber_t *fib, int need_interrupt)
|
||||||
{
|
{
|
||||||
VALUE value = fib->cont.value;
|
VALUE value = fib->cont.value;
|
||||||
VM_ASSERT(FIBER_RESUMED_P(fib));
|
rb_fiber_t *ret_fib;
|
||||||
|
|
||||||
|
VM_ASSERT(FIBER_RESUMED_P(fib));
|
||||||
rb_fiber_close(fib);
|
rb_fiber_close(fib);
|
||||||
|
|
||||||
#if FIBER_USE_NATIVE && !defined(_WIN32)
|
#if FIBER_USE_NATIVE && !defined(_WIN32)
|
||||||
@ -1721,7 +1725,9 @@ rb_fiber_terminate(rb_fiber_t *fib)
|
|||||||
fib->cont.machine.stack_size = 0;
|
fib->cont.machine.stack_size = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fiber_switch(return_fiber(), 1, &value, 0);
|
ret_fib = return_fiber();
|
||||||
|
if (need_interrupt) RUBY_VM_SET_INTERRUPT(&ret_fib->cont.saved_ec);
|
||||||
|
fiber_switch(ret_fib, 1, &value, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
2
eval.c
2
eval.c
@ -171,7 +171,7 @@ ruby_cleanup(volatile int ex)
|
|||||||
rb_threadptr_check_signal(th);
|
rb_threadptr_check_signal(th);
|
||||||
EC_PUSH_TAG(th->ec);
|
EC_PUSH_TAG(th->ec);
|
||||||
if ((state = EXEC_TAG()) == TAG_NONE) {
|
if ((state = EXEC_TAG()) == TAG_NONE) {
|
||||||
SAVE_ROOT_JMPBUF(th, { RUBY_VM_CHECK_INTS(th); });
|
SAVE_ROOT_JMPBUF(th, { RUBY_VM_CHECK_INTS(th->ec); });
|
||||||
|
|
||||||
step_0: step++;
|
step_0: step++;
|
||||||
errs[1] = th->ec->errinfo;
|
errs[1] = th->ec->errinfo;
|
||||||
|
14
insns.def
14
insns.def
@ -994,7 +994,7 @@ leave
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
|
|
||||||
if (vm_pop_frame(ec, GET_CFP(), GET_EP())) {
|
if (vm_pop_frame(ec, GET_CFP(), GET_EP())) {
|
||||||
#if OPT_CALL_THREADED_CODE
|
#if OPT_CALL_THREADED_CODE
|
||||||
@ -1024,7 +1024,7 @@ throw
|
|||||||
(VALUE throwobj)
|
(VALUE throwobj)
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
val = vm_throw(ec, GET_CFP(), throw_state, throwobj);
|
val = vm_throw(ec, GET_CFP(), throw_state, throwobj);
|
||||||
THROW_EXCEPTION(val);
|
THROW_EXCEPTION(val);
|
||||||
/* unreachable */
|
/* unreachable */
|
||||||
@ -1045,7 +1045,7 @@ jump
|
|||||||
()
|
()
|
||||||
()
|
()
|
||||||
{
|
{
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
JUMP(dst);
|
JUMP(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1061,7 +1061,7 @@ branchif
|
|||||||
()
|
()
|
||||||
{
|
{
|
||||||
if (RTEST(val)) {
|
if (RTEST(val)) {
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
JUMP(dst);
|
JUMP(dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1078,7 +1078,7 @@ branchunless
|
|||||||
()
|
()
|
||||||
{
|
{
|
||||||
if (!RTEST(val)) {
|
if (!RTEST(val)) {
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
JUMP(dst);
|
JUMP(dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1095,7 +1095,7 @@ branchnil
|
|||||||
()
|
()
|
||||||
{
|
{
|
||||||
if (NIL_P(val)) {
|
if (NIL_P(val)) {
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
JUMP(dst);
|
JUMP(dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1112,7 +1112,7 @@ branchiftype
|
|||||||
()
|
()
|
||||||
{
|
{
|
||||||
if (TYPE(val) == (int)type) {
|
if (TYPE(val) == (int)type) {
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
JUMP(dst);
|
JUMP(dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -902,8 +902,7 @@ rb_waitpid(rb_pid_t pid, int *st, int flags)
|
|||||||
else {
|
else {
|
||||||
while ((result = do_waitpid_nonblocking(pid, st, flags)) < 0 &&
|
while ((result = do_waitpid_nonblocking(pid, st, flags)) < 0 &&
|
||||||
(errno == EINTR)) {
|
(errno == EINTR)) {
|
||||||
rb_thread_t *th = GET_THREAD();
|
RUBY_VM_CHECK_INTS(GET_EC());
|
||||||
RUBY_VM_CHECK_INTS(th);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
|
14
signal.c
14
signal.c
@ -987,8 +987,8 @@ sig_do_nothing(int sig)
|
|||||||
static void
|
static void
|
||||||
signal_exec(VALUE cmd, int safe, int sig)
|
signal_exec(VALUE cmd, int safe, int sig)
|
||||||
{
|
{
|
||||||
rb_thread_t *cur_th = GET_THREAD();
|
rb_execution_context_t *ec = GET_EC();
|
||||||
volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask;
|
volatile unsigned long old_interrupt_mask = ec->interrupt_mask;
|
||||||
enum ruby_tag_type state;
|
enum ruby_tag_type state;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1000,19 +1000,19 @@ signal_exec(VALUE cmd, int safe, int sig)
|
|||||||
if (IMMEDIATE_P(cmd))
|
if (IMMEDIATE_P(cmd))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK;
|
ec->interrupt_mask |= TRAP_INTERRUPT_MASK;
|
||||||
EC_PUSH_TAG(cur_th->ec);
|
EC_PUSH_TAG(ec);
|
||||||
if ((state = EXEC_TAG()) == TAG_NONE) {
|
if ((state = EXEC_TAG()) == TAG_NONE) {
|
||||||
VALUE signum = INT2NUM(sig);
|
VALUE signum = INT2NUM(sig);
|
||||||
rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
|
rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
|
||||||
}
|
}
|
||||||
EC_POP_TAG();
|
EC_POP_TAG();
|
||||||
cur_th = GET_THREAD();
|
ec = GET_EC();
|
||||||
cur_th->interrupt_mask = old_interrupt_mask;
|
ec->interrupt_mask = old_interrupt_mask;
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
/* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
|
/* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
|
||||||
EC_JUMP_TAG(cur_th->ec, state);
|
EC_JUMP_TAG(ec, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
99
thread.c
99
thread.c
@ -96,7 +96,7 @@ static void rb_thread_sleep_deadly_allow_spurious_wakeup(void);
|
|||||||
static double timeofday(void);
|
static double timeofday(void);
|
||||||
static int rb_threadptr_dead(rb_thread_t *th);
|
static int rb_threadptr_dead(rb_thread_t *th);
|
||||||
static void rb_check_deadlock(rb_vm_t *vm);
|
static void rb_check_deadlock(rb_vm_t *vm);
|
||||||
static int rb_threadptr_pending_interrupt_empty_p(rb_thread_t *th);
|
static int rb_threadptr_pending_interrupt_empty_p(const rb_thread_t *th);
|
||||||
|
|
||||||
#define eKillSignal INT2FIX(0)
|
#define eKillSignal INT2FIX(0)
|
||||||
#define eTerminateSignal INT2FIX(1)
|
#define eTerminateSignal INT2FIX(1)
|
||||||
@ -173,17 +173,18 @@ static inline void blocking_region_end(rb_thread_t *th, struct rb_blocking_regio
|
|||||||
}; \
|
}; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define RUBY_VM_CHECK_INTS_BLOCKING(th) vm_check_ints_blocking(th)
|
#define RUBY_VM_CHECK_INTS_BLOCKING(ec) vm_check_ints_blocking(ec)
|
||||||
static inline void
|
static inline void
|
||||||
vm_check_ints_blocking(rb_thread_t *th)
|
vm_check_ints_blocking(rb_execution_context_t *ec)
|
||||||
{
|
{
|
||||||
|
rb_thread_t *th = rb_ec_thread_ptr(ec);
|
||||||
|
|
||||||
if (LIKELY(rb_threadptr_pending_interrupt_empty_p(th))) {
|
if (LIKELY(rb_threadptr_pending_interrupt_empty_p(th))) {
|
||||||
if (LIKELY(!RUBY_VM_INTERRUPTED_ANY(th))) return;
|
if (LIKELY(!RUBY_VM_INTERRUPTED_ANY(ec))) return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
th->pending_interrupt_queue_checked = 0;
|
th->pending_interrupt_queue_checked = 0;
|
||||||
|
RUBY_VM_SET_INTERRUPT(ec);
|
||||||
RUBY_VM_SET_INTERRUPT(th);
|
|
||||||
}
|
}
|
||||||
rb_threadptr_execute_interrupts(th, 1);
|
rb_threadptr_execute_interrupts(th, 1);
|
||||||
}
|
}
|
||||||
@ -381,16 +382,16 @@ unblock_function_set(rb_thread_t *th, rb_unblock_function_t *func, void *arg, in
|
|||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
if (fail_if_interrupted) {
|
if (fail_if_interrupted) {
|
||||||
if (RUBY_VM_INTERRUPTED_ANY(th)) {
|
if (RUBY_VM_INTERRUPTED_ANY(th->ec)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RUBY_VM_CHECK_INTS(th);
|
RUBY_VM_CHECK_INTS(th->ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
native_mutex_lock(&th->interrupt_lock);
|
native_mutex_lock(&th->interrupt_lock);
|
||||||
} while (RUBY_VM_INTERRUPTED_ANY(th) &&
|
} while (RUBY_VM_INTERRUPTED_ANY(th->ec) &&
|
||||||
(native_mutex_unlock(&th->interrupt_lock), TRUE));
|
(native_mutex_unlock(&th->interrupt_lock), TRUE));
|
||||||
|
|
||||||
VM_ASSERT(th->unblock.func == NULL);
|
VM_ASSERT(th->unblock.func == NULL);
|
||||||
@ -415,10 +416,10 @@ rb_threadptr_interrupt_common(rb_thread_t *th, int trap)
|
|||||||
{
|
{
|
||||||
native_mutex_lock(&th->interrupt_lock);
|
native_mutex_lock(&th->interrupt_lock);
|
||||||
if (trap) {
|
if (trap) {
|
||||||
RUBY_VM_SET_TRAP_INTERRUPT(th);
|
RUBY_VM_SET_TRAP_INTERRUPT(th->ec);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RUBY_VM_SET_INTERRUPT(th);
|
RUBY_VM_SET_INTERRUPT(th->ec);
|
||||||
}
|
}
|
||||||
if (th->unblock.func != NULL) {
|
if (th->unblock.func != NULL) {
|
||||||
(th->unblock.func)(th->unblock.arg);
|
(th->unblock.func)(th->unblock.arg);
|
||||||
@ -479,6 +480,7 @@ void
|
|||||||
rb_thread_terminate_all(void)
|
rb_thread_terminate_all(void)
|
||||||
{
|
{
|
||||||
rb_thread_t *volatile th = GET_THREAD(); /* main thread */
|
rb_thread_t *volatile th = GET_THREAD(); /* main thread */
|
||||||
|
rb_execution_context_t * volatile ec = th->ec;
|
||||||
rb_vm_t *volatile vm = th->vm;
|
rb_vm_t *volatile vm = th->vm;
|
||||||
volatile int sleeping = 0;
|
volatile int sleeping = 0;
|
||||||
|
|
||||||
@ -490,7 +492,7 @@ rb_thread_terminate_all(void)
|
|||||||
/* unlock all locking mutexes */
|
/* unlock all locking mutexes */
|
||||||
rb_threadptr_unlock_all_locking_mutexes(th);
|
rb_threadptr_unlock_all_locking_mutexes(th);
|
||||||
|
|
||||||
EC_PUSH_TAG(th->ec);
|
EC_PUSH_TAG(ec);
|
||||||
if (EC_EXEC_TAG() == TAG_NONE) {
|
if (EC_EXEC_TAG() == TAG_NONE) {
|
||||||
retry:
|
retry:
|
||||||
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
|
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
|
||||||
@ -503,7 +505,7 @@ rb_thread_terminate_all(void)
|
|||||||
*/
|
*/
|
||||||
sleeping = 1;
|
sleeping = 1;
|
||||||
native_sleep(th, 0);
|
native_sleep(th, 0);
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(ec);
|
||||||
sleeping = 0;
|
sleeping = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -732,8 +734,6 @@ thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(ANYARGS))
|
|||||||
th->pending_interrupt_mask_stack = rb_ary_dup(current_th->pending_interrupt_mask_stack);
|
th->pending_interrupt_mask_stack = rb_ary_dup(current_th->pending_interrupt_mask_stack);
|
||||||
RBASIC_CLEAR_CLASS(th->pending_interrupt_mask_stack);
|
RBASIC_CLEAR_CLASS(th->pending_interrupt_mask_stack);
|
||||||
|
|
||||||
th->interrupt_mask = 0;
|
|
||||||
|
|
||||||
native_mutex_initialize(&th->interrupt_lock);
|
native_mutex_initialize(&th->interrupt_lock);
|
||||||
th->report_on_exception = th->vm->thread_report_on_exception;
|
th->report_on_exception = th->vm->thread_report_on_exception;
|
||||||
|
|
||||||
@ -1079,7 +1079,7 @@ sleep_forever(rb_thread_t *th, int deadlockable, int spurious_check)
|
|||||||
enum rb_thread_status status = deadlockable ? THREAD_STOPPED_FOREVER : THREAD_STOPPED;
|
enum rb_thread_status status = deadlockable ? THREAD_STOPPED_FOREVER : THREAD_STOPPED;
|
||||||
|
|
||||||
th->status = status;
|
th->status = status;
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||||
while (th->status == status) {
|
while (th->status == status) {
|
||||||
if (deadlockable) {
|
if (deadlockable) {
|
||||||
th->vm->sleeper++;
|
th->vm->sleeper++;
|
||||||
@ -1089,7 +1089,7 @@ sleep_forever(rb_thread_t *th, int deadlockable, int spurious_check)
|
|||||||
if (deadlockable) {
|
if (deadlockable) {
|
||||||
th->vm->sleeper--;
|
th->vm->sleeper--;
|
||||||
}
|
}
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||||
if (!spurious_check)
|
if (!spurious_check)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1134,10 +1134,10 @@ sleep_timeval(rb_thread_t *th, struct timeval tv, int spurious_check)
|
|||||||
}
|
}
|
||||||
|
|
||||||
th->status = THREAD_STOPPED;
|
th->status = THREAD_STOPPED;
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||||
while (th->status == THREAD_STOPPED) {
|
while (th->status == THREAD_STOPPED) {
|
||||||
native_sleep(th, &tv);
|
native_sleep(th, &tv);
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||||
getclockofday(&tvn);
|
getclockofday(&tvn);
|
||||||
if (to.tv_sec < tvn.tv_sec) break;
|
if (to.tv_sec < tvn.tv_sec) break;
|
||||||
if (to.tv_sec == tvn.tv_sec && to.tv_usec <= tvn.tv_usec) break;
|
if (to.tv_sec == tvn.tv_sec && to.tv_usec <= tvn.tv_usec) break;
|
||||||
@ -1217,8 +1217,7 @@ rb_thread_wait_for(struct timeval time)
|
|||||||
void
|
void
|
||||||
rb_thread_check_ints(void)
|
rb_thread_check_ints(void)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = GET_THREAD();
|
RUBY_VM_CHECK_INTS_BLOCKING(GET_EC());
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1235,7 +1234,7 @@ rb_thread_check_trap_pending(void)
|
|||||||
int
|
int
|
||||||
rb_thread_interrupted(VALUE thval)
|
rb_thread_interrupted(VALUE thval)
|
||||||
{
|
{
|
||||||
return (int)RUBY_VM_INTERRUPTED(rb_thread_ptr(thval));
|
return (int)RUBY_VM_INTERRUPTED(rb_thread_ptr(thval)->ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1264,10 +1263,8 @@ rb_thread_schedule_limits(uint32_t limits_us)
|
|||||||
void
|
void
|
||||||
rb_thread_schedule(void)
|
rb_thread_schedule(void)
|
||||||
{
|
{
|
||||||
rb_thread_t *cur_th = GET_THREAD();
|
|
||||||
rb_thread_schedule_limits(0);
|
rb_thread_schedule_limits(0);
|
||||||
|
RUBY_VM_CHECK_INTS(GET_EC());
|
||||||
RUBY_VM_CHECK_INTS(cur_th);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* blocking region */
|
/* blocking region */
|
||||||
@ -1324,7 +1321,7 @@ call_without_gvl(void *(*func)(void *), void *data1,
|
|||||||
}, ubf, data2, fail_if_interrupted);
|
}, ubf, data2, fail_if_interrupted);
|
||||||
|
|
||||||
if (!fail_if_interrupted) {
|
if (!fail_if_interrupted) {
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
@ -1435,22 +1432,21 @@ VALUE
|
|||||||
rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
|
rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
|
||||||
{
|
{
|
||||||
volatile VALUE val = Qundef; /* shouldn't be used */
|
volatile VALUE val = Qundef; /* shouldn't be used */
|
||||||
rb_vm_t *vm = GET_VM();
|
rb_execution_context_t * volatile ec = GET_EC();
|
||||||
rb_thread_t *volatile th = GET_THREAD();
|
|
||||||
volatile int saved_errno = 0;
|
volatile int saved_errno = 0;
|
||||||
enum ruby_tag_type state;
|
enum ruby_tag_type state;
|
||||||
struct waiting_fd wfd;
|
struct waiting_fd wfd;
|
||||||
|
|
||||||
wfd.fd = fd;
|
wfd.fd = fd;
|
||||||
wfd.th = th;
|
wfd.th = rb_ec_thread_ptr(ec);
|
||||||
list_add(&vm->waiting_fds, &wfd.wfd_node);
|
list_add(&rb_ec_vm_ptr(ec)->waiting_fds, &wfd.wfd_node);
|
||||||
|
|
||||||
EC_PUSH_TAG(th->ec);
|
EC_PUSH_TAG(ec);
|
||||||
if ((state = EXEC_TAG()) == TAG_NONE) {
|
if ((state = EXEC_TAG()) == TAG_NONE) {
|
||||||
BLOCKING_REGION({
|
BLOCKING_REGION({
|
||||||
val = func(data1);
|
val = func(data1);
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
}, ubf_select, th, FALSE);
|
}, ubf_select, rb_ec_thread_ptr(ec), FALSE);
|
||||||
}
|
}
|
||||||
EC_POP_TAG();
|
EC_POP_TAG();
|
||||||
|
|
||||||
@ -1458,10 +1454,10 @@ rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd)
|
|||||||
list_del(&wfd.wfd_node);
|
list_del(&wfd.wfd_node);
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
EC_JUMP_TAG(th->ec, state);
|
EC_JUMP_TAG(ec, state);
|
||||||
}
|
}
|
||||||
/* TODO: check func() */
|
/* TODO: check func() */
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(ec);
|
||||||
|
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
|
||||||
@ -1656,7 +1652,7 @@ rb_threadptr_pending_interrupt_check_mask(rb_thread_t *th, VALUE err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rb_threadptr_pending_interrupt_empty_p(rb_thread_t *th)
|
rb_threadptr_pending_interrupt_empty_p(const rb_thread_t *th)
|
||||||
{
|
{
|
||||||
return RARRAY_LEN(th->pending_interrupt_queue) == 0;
|
return RARRAY_LEN(th->pending_interrupt_queue) == 0;
|
||||||
}
|
}
|
||||||
@ -1857,7 +1853,8 @@ static VALUE
|
|||||||
rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg)
|
rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg)
|
||||||
{
|
{
|
||||||
VALUE mask;
|
VALUE mask;
|
||||||
rb_thread_t * volatile th = GET_THREAD();
|
rb_execution_context_t * volatile ec = GET_EC();
|
||||||
|
rb_thread_t * volatile th = rb_ec_thread_ptr(ec);
|
||||||
volatile VALUE r = Qnil;
|
volatile VALUE r = Qnil;
|
||||||
enum ruby_tag_type state;
|
enum ruby_tag_type state;
|
||||||
|
|
||||||
@ -1875,7 +1872,7 @@ rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg)
|
|||||||
rb_ary_push(th->pending_interrupt_mask_stack, mask);
|
rb_ary_push(th->pending_interrupt_mask_stack, mask);
|
||||||
if (!rb_threadptr_pending_interrupt_empty_p(th)) {
|
if (!rb_threadptr_pending_interrupt_empty_p(th)) {
|
||||||
th->pending_interrupt_queue_checked = 0;
|
th->pending_interrupt_queue_checked = 0;
|
||||||
RUBY_VM_SET_INTERRUPT(th);
|
RUBY_VM_SET_INTERRUPT(th->ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
EC_PUSH_TAG(th->ec);
|
EC_PUSH_TAG(th->ec);
|
||||||
@ -1887,10 +1884,10 @@ rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg)
|
|||||||
rb_ary_pop(th->pending_interrupt_mask_stack);
|
rb_ary_pop(th->pending_interrupt_mask_stack);
|
||||||
if (!rb_threadptr_pending_interrupt_empty_p(th)) {
|
if (!rb_threadptr_pending_interrupt_empty_p(th)) {
|
||||||
th->pending_interrupt_queue_checked = 0;
|
th->pending_interrupt_queue_checked = 0;
|
||||||
RUBY_VM_SET_INTERRUPT(th);
|
RUBY_VM_SET_INTERRUPT(th->ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS(th);
|
RUBY_VM_CHECK_INTS(th->ec);
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
EC_JUMP_TAG(th->ec, state);
|
EC_JUMP_TAG(th->ec, state);
|
||||||
@ -2014,14 +2011,15 @@ rb_threadptr_to_kill(rb_thread_t *th)
|
|||||||
static inline rb_atomic_t
|
static inline rb_atomic_t
|
||||||
threadptr_get_interrupts(rb_thread_t *th)
|
threadptr_get_interrupts(rb_thread_t *th)
|
||||||
{
|
{
|
||||||
|
rb_execution_context_t *ec = th->ec;
|
||||||
rb_atomic_t interrupt;
|
rb_atomic_t interrupt;
|
||||||
rb_atomic_t old;
|
rb_atomic_t old;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
interrupt = th->interrupt_flag;
|
interrupt = ec->interrupt_flag;
|
||||||
old = ATOMIC_CAS(th->interrupt_flag, interrupt, interrupt & th->interrupt_mask);
|
old = ATOMIC_CAS(ec->interrupt_flag, interrupt, interrupt & ec->interrupt_mask);
|
||||||
} while (old != interrupt);
|
} while (old != interrupt);
|
||||||
return interrupt & (rb_atomic_t)~th->interrupt_mask;
|
return interrupt & (rb_atomic_t)~ec->interrupt_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2252,7 +2250,7 @@ thread_raise_m(int argc, VALUE *argv, VALUE self)
|
|||||||
|
|
||||||
/* To perform Thread.current.raise as Kernel.raise */
|
/* To perform Thread.current.raise as Kernel.raise */
|
||||||
if (current_th == target_th) {
|
if (current_th == target_th) {
|
||||||
RUBY_VM_CHECK_INTS(target_th);
|
RUBY_VM_CHECK_INTS(target_th->ec);
|
||||||
}
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
@ -3734,7 +3732,7 @@ do_select(int n, rb_fdset_t *const readfds, rb_fdset_t *const writefds,
|
|||||||
if (result < 0) lerrno = errno;
|
if (result < 0) lerrno = errno;
|
||||||
}, ubf_select, th, FALSE);
|
}, ubf_select, th, FALSE);
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||||
} while (result < 0 && retryable(errno = lerrno) && do_select_update());
|
} while (result < 0 && retryable(errno = lerrno) && do_select_update());
|
||||||
|
|
||||||
#define fd_term(f) if (f##fds) rb_fd_term(&orig_##f)
|
#define fd_term(f) if (f##fds) rb_fd_term(&orig_##f)
|
||||||
@ -3898,7 +3896,7 @@ rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
|
|||||||
if (result < 0) lerrno = errno;
|
if (result < 0) lerrno = errno;
|
||||||
}, ubf_select, th, FALSE);
|
}, ubf_select, th, FALSE);
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||||
} while (result < 0 && retryable(errno = lerrno) && poll_update());
|
} while (result < 0 && retryable(errno = lerrno) && poll_update());
|
||||||
if (result < 0) return -1;
|
if (result < 0) return -1;
|
||||||
|
|
||||||
@ -4041,8 +4039,9 @@ timer_thread_function(void *arg)
|
|||||||
*/
|
*/
|
||||||
native_mutex_lock(&vm->thread_destruct_lock);
|
native_mutex_lock(&vm->thread_destruct_lock);
|
||||||
/* for time slice */
|
/* for time slice */
|
||||||
if (vm->running_thread)
|
if (vm->running_thread) {
|
||||||
RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread);
|
RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread->ec);
|
||||||
|
}
|
||||||
native_mutex_unlock(&vm->thread_destruct_lock);
|
native_mutex_unlock(&vm->thread_destruct_lock);
|
||||||
|
|
||||||
/* check signal */
|
/* check signal */
|
||||||
@ -4890,8 +4889,6 @@ Init_Thread(void)
|
|||||||
th->pending_interrupt_queue = rb_ary_tmp_new(0);
|
th->pending_interrupt_queue = rb_ary_tmp_new(0);
|
||||||
th->pending_interrupt_queue_checked = 0;
|
th->pending_interrupt_queue_checked = 0;
|
||||||
th->pending_interrupt_mask_stack = rb_ary_tmp_new(0);
|
th->pending_interrupt_mask_stack = rb_ary_tmp_new(0);
|
||||||
|
|
||||||
th->interrupt_mask = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4922,7 +4919,7 @@ debug_deadlock_check(rb_vm_t *vm, VALUE msg)
|
|||||||
list_for_each(&vm->living_threads, th, vmlt_node) {
|
list_for_each(&vm->living_threads, th, vmlt_node) {
|
||||||
rb_str_catf(msg, "* %+"PRIsVALUE"\n rb_thread_t:%p "
|
rb_str_catf(msg, "* %+"PRIsVALUE"\n rb_thread_t:%p "
|
||||||
"native:%"PRI_THREAD_ID" int:%u",
|
"native:%"PRI_THREAD_ID" int:%u",
|
||||||
th->self, th, thread_id_str(th), th->interrupt_flag);
|
th->self, th, thread_id_str(th), th->ec->interrupt_flag);
|
||||||
if (th->locking_mutex) {
|
if (th->locking_mutex) {
|
||||||
rb_mutex_t *mutex;
|
rb_mutex_t *mutex;
|
||||||
GetMutexPtr(th->locking_mutex, mutex);
|
GetMutexPtr(th->locking_mutex, mutex);
|
||||||
@ -4953,7 +4950,7 @@ rb_check_deadlock(rb_vm_t *vm)
|
|||||||
if (patrol_thread && patrol_thread != GET_THREAD()) return;
|
if (patrol_thread && patrol_thread != GET_THREAD()) return;
|
||||||
|
|
||||||
list_for_each(&vm->living_threads, th, vmlt_node) {
|
list_for_each(&vm->living_threads, th, vmlt_node) {
|
||||||
if (th->status != THREAD_STOPPED_FOREVER || RUBY_VM_INTERRUPTED(th)) {
|
if (th->status != THREAD_STOPPED_FOREVER || RUBY_VM_INTERRUPTED(th->ec)) {
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
else if (th->locking_mutex) {
|
else if (th->locking_mutex) {
|
||||||
|
@ -1132,7 +1132,7 @@ native_sleep(rb_thread_t *th, struct timeval *timeout_tv)
|
|||||||
th->unblock.func = ubf_pthread_cond_signal;
|
th->unblock.func = ubf_pthread_cond_signal;
|
||||||
th->unblock.arg = th;
|
th->unblock.arg = th;
|
||||||
|
|
||||||
if (RUBY_VM_INTERRUPTED(th)) {
|
if (RUBY_VM_INTERRUPTED(th->ec)) {
|
||||||
/* interrupted. return immediate */
|
/* interrupted. return immediate */
|
||||||
thread_debug("native_sleep: interrupted before sleep\n");
|
thread_debug("native_sleep: interrupted before sleep\n");
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ rb_mutex_lock(VALUE self)
|
|||||||
|
|
||||||
/* When running trap handler */
|
/* When running trap handler */
|
||||||
if (!FL_TEST_RAW(self, MUTEX_ALLOW_TRAP) &&
|
if (!FL_TEST_RAW(self, MUTEX_ALLOW_TRAP) &&
|
||||||
th->interrupt_mask & TRAP_INTERRUPT_MASK) {
|
th->ec->interrupt_mask & TRAP_INTERRUPT_MASK) {
|
||||||
rb_raise(rb_eThreadError, "can't be called from trap context");
|
rb_raise(rb_eThreadError, "can't be called from trap context");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ rb_mutex_lock(VALUE self)
|
|||||||
patrol_thread = NULL;
|
patrol_thread = NULL;
|
||||||
|
|
||||||
th->locking_mutex = Qfalse;
|
th->locking_mutex = Qfalse;
|
||||||
if (mutex->th && timeout && !RUBY_VM_INTERRUPTED(th)) {
|
if (mutex->th && timeout && !RUBY_VM_INTERRUPTED(th->ec)) {
|
||||||
rb_check_deadlock(th->vm);
|
rb_check_deadlock(th->vm);
|
||||||
}
|
}
|
||||||
if (th->status == THREAD_STOPPED_FOREVER) {
|
if (th->status == THREAD_STOPPED_FOREVER) {
|
||||||
@ -290,7 +290,7 @@ rb_mutex_lock(VALUE self)
|
|||||||
|
|
||||||
if (mutex->th == th) mutex_locked(th, self);
|
if (mutex->th == th) mutex_locked(th, self);
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(th);
|
RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -167,7 +167,7 @@ w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th)
|
|||||||
thread_debug(" w32_wait_events events:%p, count:%d, timeout:%ld, th:%p\n",
|
thread_debug(" w32_wait_events events:%p, count:%d, timeout:%ld, th:%p\n",
|
||||||
events, count, timeout, th);
|
events, count, timeout, th);
|
||||||
if (th && (intr = th->native_thread_data.interrupt_event)) {
|
if (th && (intr = th->native_thread_data.interrupt_event)) {
|
||||||
if (ResetEvent(intr) && (!RUBY_VM_INTERRUPTED(th) || SetEvent(intr))) {
|
if (ResetEvent(intr) && (!RUBY_VM_INTERRUPTED(th->ec) || SetEvent(intr))) {
|
||||||
targets = ALLOCA_N(HANDLE, count + 1);
|
targets = ALLOCA_N(HANDLE, count + 1);
|
||||||
memcpy(targets, events, sizeof(HANDLE) * count);
|
memcpy(targets, events, sizeof(HANDLE) * count);
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ native_sleep(rb_thread_t *th, struct timeval *tv)
|
|||||||
th->unblock.arg = th;
|
th->unblock.arg = th;
|
||||||
native_mutex_unlock(&th->interrupt_lock);
|
native_mutex_unlock(&th->interrupt_lock);
|
||||||
|
|
||||||
if (RUBY_VM_INTERRUPTED(th)) {
|
if (RUBY_VM_INTERRUPTED(th->ec)) {
|
||||||
/* interrupted. return immediate */
|
/* interrupted. return immediate */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
30
vm_core.h
30
vm_core.h
@ -745,6 +745,10 @@ typedef struct rb_execution_context_struct {
|
|||||||
int safe_level;
|
int safe_level;
|
||||||
int raised_flag;
|
int raised_flag;
|
||||||
|
|
||||||
|
/* interrupt flags */
|
||||||
|
rb_atomic_t interrupt_flag;
|
||||||
|
unsigned long interrupt_mask;
|
||||||
|
|
||||||
rb_fiber_t *fiber_ptr;
|
rb_fiber_t *fiber_ptr;
|
||||||
struct rb_thread_struct *thread_ptr;
|
struct rb_thread_struct *thread_ptr;
|
||||||
|
|
||||||
@ -825,8 +829,7 @@ typedef struct rb_thread_struct {
|
|||||||
VALUE pending_interrupt_mask_stack;
|
VALUE pending_interrupt_mask_stack;
|
||||||
int pending_interrupt_queue_checked;
|
int pending_interrupt_queue_checked;
|
||||||
|
|
||||||
rb_atomic_t interrupt_flag;
|
/* interrupt management */
|
||||||
unsigned long interrupt_mask;
|
|
||||||
rb_nativethread_lock_t interrupt_lock;
|
rb_nativethread_lock_t interrupt_lock;
|
||||||
struct rb_unblock_callback unblock;
|
struct rb_unblock_callback unblock;
|
||||||
VALUE locking_mutex;
|
VALUE locking_mutex;
|
||||||
@ -1652,12 +1655,13 @@ enum {
|
|||||||
TRAP_INTERRUPT_MASK = 0x08
|
TRAP_INTERRUPT_MASK = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RUBY_VM_SET_TIMER_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, TIMER_INTERRUPT_MASK)
|
#define RUBY_VM_SET_TIMER_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, TIMER_INTERRUPT_MASK)
|
||||||
#define RUBY_VM_SET_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, PENDING_INTERRUPT_MASK)
|
#define RUBY_VM_SET_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, PENDING_INTERRUPT_MASK)
|
||||||
#define RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, POSTPONED_JOB_INTERRUPT_MASK)
|
#define RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, POSTPONED_JOB_INTERRUPT_MASK)
|
||||||
#define RUBY_VM_SET_TRAP_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, TRAP_INTERRUPT_MASK)
|
#define RUBY_VM_SET_TRAP_INTERRUPT(ec) ATOMIC_OR((ec)->interrupt_flag, TRAP_INTERRUPT_MASK)
|
||||||
#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & ~(th)->interrupt_mask & (PENDING_INTERRUPT_MASK|TRAP_INTERRUPT_MASK))
|
#define RUBY_VM_INTERRUPTED(ec) ((ec)->interrupt_flag & ~(ec)->interrupt_mask & \
|
||||||
#define RUBY_VM_INTERRUPTED_ANY(th) ((th)->interrupt_flag & ~(th)->interrupt_mask)
|
(PENDING_INTERRUPT_MASK|TRAP_INTERRUPT_MASK))
|
||||||
|
#define RUBY_VM_INTERRUPTED_ANY(ec) ((ec)->interrupt_flag & ~(ec)->interrupt_mask)
|
||||||
|
|
||||||
VALUE rb_exc_set_backtrace(VALUE exc, VALUE bt);
|
VALUE rb_exc_set_backtrace(VALUE exc, VALUE bt);
|
||||||
int rb_signal_buff_size(void);
|
int rb_signal_buff_size(void);
|
||||||
@ -1676,13 +1680,13 @@ void rb_execution_context_mark(const rb_execution_context_t *ec);
|
|||||||
void rb_fiber_close(rb_fiber_t *fib);
|
void rb_fiber_close(rb_fiber_t *fib);
|
||||||
void Init_native_thread(rb_thread_t *th);
|
void Init_native_thread(rb_thread_t *th);
|
||||||
|
|
||||||
#define RUBY_VM_CHECK_INTS(th) ruby_vm_check_ints(th)
|
#define RUBY_VM_CHECK_INTS(ec) ruby_vm_check_ints(ec)
|
||||||
static inline void
|
static inline void
|
||||||
ruby_vm_check_ints(rb_thread_t *th)
|
ruby_vm_check_ints(rb_execution_context_t *ec)
|
||||||
{
|
{
|
||||||
VM_ASSERT(th->ec == ruby_current_execution_context_ptr);
|
VM_ASSERT(ec == ruby_current_execution_context_ptr);
|
||||||
if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(th))) {
|
if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {
|
||||||
rb_threadptr_execute_interrupts(th, 0);
|
rb_threadptr_execute_interrupts(rb_ec_thread_ptr(ec), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const
|
|||||||
ret = method_missing(calling->recv, ci->mid, calling->argc, argv, ex);
|
ret = method_missing(calling->recv, ci->mid, calling->argc, argv, ex);
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
case VM_METHOD_TYPE_ALIAS:
|
case VM_METHOD_TYPE_ALIAS:
|
||||||
@ -197,7 +197,7 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const
|
|||||||
return Qundef;
|
return Qundef;
|
||||||
|
|
||||||
success:
|
success:
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1712,7 +1712,7 @@ vm_call_iseq_setup_tailcall(rb_execution_context_t *ec, rb_control_frame_t *cfp,
|
|||||||
iseq->body->stack_max);
|
iseq->body->stack_max);
|
||||||
|
|
||||||
cfp->sp = sp_orig;
|
cfp->sp = sp_orig;
|
||||||
RUBY_VM_CHECK_INTS(rb_ec_thread_ptr(ec));
|
RUBY_VM_CHECK_INTS(ec);
|
||||||
|
|
||||||
return Qundef;
|
return Qundef;
|
||||||
}
|
}
|
||||||
@ -3284,7 +3284,7 @@ vm_once_dispatch(ISEQ iseq, IC ic, rb_thread_t *th)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* waiting for finish */
|
/* waiting for finish */
|
||||||
RUBY_VM_CHECK_INTS(th);
|
RUBY_VM_CHECK_INTS(th->ec);
|
||||||
rb_thread_schedule();
|
rb_thread_schedule();
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
20
vm_trace.c
20
vm_trace.c
@ -1540,7 +1540,7 @@ postponed_job_register(rb_thread_t *th, rb_vm_t *vm,
|
|||||||
pjob->func = func;
|
pjob->func = func;
|
||||||
pjob->data = data;
|
pjob->data = data;
|
||||||
|
|
||||||
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(th);
|
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(th->ec);
|
||||||
|
|
||||||
return PJRR_SUCESS;
|
return PJRR_SUCESS;
|
||||||
}
|
}
|
||||||
@ -1576,7 +1576,7 @@ rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func,
|
|||||||
for (i=0; i<index; i++) {
|
for (i=0; i<index; i++) {
|
||||||
pjob = &vm->postponed_job_buffer[i];
|
pjob = &vm->postponed_job_buffer[i];
|
||||||
if (pjob->func == func) {
|
if (pjob->func == func) {
|
||||||
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(th);
|
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(th->ec);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1591,16 +1591,16 @@ rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func,
|
|||||||
void
|
void
|
||||||
rb_postponed_job_flush(rb_vm_t *vm)
|
rb_postponed_job_flush(rb_vm_t *vm)
|
||||||
{
|
{
|
||||||
rb_thread_t * volatile th = GET_THREAD();
|
rb_execution_context_t *ec = GET_EC();
|
||||||
const unsigned long block_mask = POSTPONED_JOB_INTERRUPT_MASK|TRAP_INTERRUPT_MASK;
|
const unsigned long block_mask = POSTPONED_JOB_INTERRUPT_MASK|TRAP_INTERRUPT_MASK;
|
||||||
volatile unsigned long saved_mask = th->interrupt_mask & block_mask;
|
volatile unsigned long saved_mask = ec->interrupt_mask & block_mask;
|
||||||
VALUE volatile saved_errno = th->ec->errinfo;
|
VALUE volatile saved_errno = ec->errinfo;
|
||||||
|
|
||||||
th->ec->errinfo = Qnil;
|
ec->errinfo = Qnil;
|
||||||
/* mask POSTPONED_JOB dispatch */
|
/* mask POSTPONED_JOB dispatch */
|
||||||
th->interrupt_mask |= block_mask;
|
ec->interrupt_mask |= block_mask;
|
||||||
{
|
{
|
||||||
EC_PUSH_TAG(th->ec);
|
EC_PUSH_TAG(ec);
|
||||||
if (EXEC_TAG() == TAG_NONE) {
|
if (EXEC_TAG() == TAG_NONE) {
|
||||||
int index;
|
int index;
|
||||||
while ((index = vm->postponed_job_index) > 0) {
|
while ((index = vm->postponed_job_index) > 0) {
|
||||||
@ -1613,6 +1613,6 @@ rb_postponed_job_flush(rb_vm_t *vm)
|
|||||||
EC_POP_TAG();
|
EC_POP_TAG();
|
||||||
}
|
}
|
||||||
/* restore POSTPONED_JOB mask */
|
/* restore POSTPONED_JOB mask */
|
||||||
th->interrupt_mask &= ~(saved_mask ^ block_mask);
|
ec->interrupt_mask &= ~(saved_mask ^ block_mask);
|
||||||
th->ec->errinfo = saved_errno;
|
ec->errinfo = saved_errno;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user