diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-05-30 01:52:38 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-05-30 01:52:38 +0000 |
commit | 1b63d7bc927ace82f91704d6472d90511209f944 (patch) | |
tree | d686c70e7069ec3e2eb23bad3c40a418b39b2505 /thread.c | |
parent | b9ff5a2fd6d24ce828184729addc40d2825a8896 (diff) | |
download | ruby-1b63d7bc927ace82f91704d6472d90511209f944.tar.gz |
* vm_core.h (struct rb_unblock_callback), thread.c
(set_unblock_function), thread_{pthread,win32}.c (native_sleep):
extracted from struct rb_thread_struct.
* thread.c (reset_unblock_function): not check interrupts at leaving
blocking region. [ruby-dev:34874]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16699 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
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 */ |