diff options
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 33 |
1 files changed, 20 insertions, 13 deletions
@@ -79,8 +79,9 @@ st_delete_wrap(st_table *table, st_data_t key) #define THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION -static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *ptr, - rb_unblock_function_t **oldfunc, void **oldptr); +static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *arg, + struct rb_unblock_callback *old); +static void reset_unblock_function(rb_thread_t *th, const struct rb_unblock_callback *old); #define GVL_UNLOCK_BEGIN() do { \ rb_thread_t *_th_stored = GET_THREAD(); \ @@ -95,9 +96,8 @@ static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, v #define BLOCKING_REGION(exec, ubf, ubfarg) do { \ rb_thread_t *__th = GET_THREAD(); \ int __prev_status = __th->status; \ - rb_unblock_function_t *__oldubf; \ - void *__oldubfarg; \ - set_unblock_function(__th, ubf, ubfarg, &__oldubf, &__oldubfarg); \ + struct rb_unblock_callback __oldubf; \ + set_unblock_function(__th, ubf, ubfarg, &__oldubf); \ __th->status = THREAD_STOPPED; \ thread_debug("enter blocking region (%p)\n", __th); \ GVL_UNLOCK_BEGIN(); {\ @@ -106,7 +106,7 @@ static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, v GVL_UNLOCK_END(); \ thread_debug("leave blocking region (%p)\n", __th); \ remove_signal_thread_list(__th); \ - set_unblock_function(__th, __oldubf, __oldubfarg, 0, 0); \ + reset_unblock_function(__th, &__oldubf); \ if (__th->status == THREAD_STOPPED) { \ __th->status = __prev_status; \ } \ @@ -195,7 +195,7 @@ rb_thread_debug(const char *fmt, ...) static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *arg, - rb_unblock_function_t **oldfunc, void **oldarg) + struct rb_unblock_callback *old) { check_ints: RUBY_VM_CHECK_INTS(); /* check signal or so */ @@ -205,21 +205,28 @@ set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *arg, goto check_ints; } else { - if (oldfunc) *oldfunc = th->unblock_function; - if (oldarg) *oldarg = th->unblock_function_arg; - th->unblock_function = func; - th->unblock_function_arg = arg; + if (old) *old = th->unblock; + th->unblock.func = func; + th->unblock.arg = arg; } native_mutex_unlock(&th->interrupt_lock); } static void +reset_unblock_function(rb_thread_t *th, const struct rb_unblock_callback *old) +{ + native_mutex_lock(&th->interrupt_lock); + th->unblock = *old; + native_mutex_unlock(&th->interrupt_lock); +} + +static void rb_thread_interrupt(rb_thread_t *th) { native_mutex_lock(&th->interrupt_lock); RUBY_VM_SET_INTERRUPT(th); - if (th->unblock_function) { - (th->unblock_function)(th->unblock_function_arg); + if (th->unblock.func) { + (th->unblock.func)(th->unblock.arg); } else { /* none */ |