From f425798fdaca165c200091faf976c3cf9a52637d Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 24 Feb 2007 09:41:41 +0000 Subject: * intern.h (rb_thread_blocking_region): add prototype. * thread.c (BLOCKING_REGION): restore previous UBF. * thread.c (rb_thread_blocking_region): default UBF to interrupt in system dependent way by RB_UBF_DFL. + ubf_select() on posix system + ubf_handle() on Win32 + none on cygwin git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11861 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 +++++++++++- intern.h | 7 +++++++ thread.c | 25 ++++++++++++++++++------- thread_pthread.ci | 2 ++ yarvcore.h | 8 ++------ 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 99fc2a3220..a48e5b3883 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,17 @@ -Sat Feb 24 18:39:15 2007 Nobuyoshi Nakada +Sat Feb 24 18:41:30 2007 Nobuyoshi Nakada + + * intern.h (rb_thread_blocking_region): add prototype. * thread.c (rb_thread_debug): added runtime debugging flag. + * thread.c (BLOCKING_REGION): restore previous UBF. + + * thread.c (rb_thread_blocking_region): default UBF to interrupt + in system dependent way by RB_UBF_DFL. + + ubf_select() on posix system + + ubf_handle() on Win32 + + none on cygwin + Sat Feb 24 17:45:48 2007 Minero Aoki * parse.y (f_arg, opt_f_block_arg): ripper should export VALUE. diff --git a/intern.h b/intern.h index 7b2a6a7e95..fcf553976f 100644 --- a/intern.h +++ b/intern.h @@ -536,6 +536,13 @@ VALUE rb_struct_getmember(VALUE, ID); VALUE rb_struct_iv_get(VALUE, const char*); VALUE rb_struct_s_members(VALUE); VALUE rb_struct_members(VALUE); +/* thread.c */ +typedef struct rb_thread_struct rb_thread_t; +typedef void rb_unblock_function_t(rb_thread_t *); +typedef VALUE rb_blocking_function_t(rb_thread_t *th, void *); +VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data, + rb_unblock_function_t *ubf); +#define RB_UBF_DFL ((rb_unblock_function_t *)-1) /* time.c */ VALUE rb_time_new(time_t, time_t); /* variable.c */ diff --git a/thread.c b/thread.c index 424fc82af2..9cd676dbb2 100644 --- a/thread.c +++ b/thread.c @@ -78,7 +78,7 @@ st_delete_wrap(st_table * table, VALUE key) #define THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION -static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func); +static rb_unblock_function_t* set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func); static void clear_unblock_function(rb_thread_t *th); NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p)); @@ -97,14 +97,16 @@ NOINLINE(void rb_gc_save_machine_context(rb_thread_t *)); #define BLOCKING_REGION(exec, ubf) do { \ rb_thread_t *__th = GET_THREAD(); \ int __prev_status = __th->status; \ - set_unblock_function(__th, ubf); \ + rb_unblock_function_t *__oldubf = set_unblock_function(__th, ubf); \ __th->status = THREAD_STOPPED; \ + thread_debug("enter blocking region (%p)\n", __th); \ GVL_UNLOCK_BEGIN(); {\ exec; \ } \ GVL_UNLOCK_END(); \ + thread_debug("leave blocking region (%p)\n", __th); \ remove_signal_thread_list(__th); \ - clear_unblock_function(__th); \ + set_unblock_function(__th, __oldubf); \ if (__th->status == THREAD_STOPPED) { \ __th->status = __prev_status; \ } \ @@ -185,20 +187,26 @@ rb_thread_debug(const char *fmt, ...) #endif -static void +static rb_unblock_function_t * set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func) { + rb_unblock_function_t *oldfunc; + int interrupted; + check_ints: RUBY_VM_CHECK_INTS(); /* check signal or so */ native_mutex_lock(&th->interrupt_lock); if (th->interrupt_flag) { native_mutex_unlock(&th->interrupt_lock); - goto check_ints; - } + goto check_ints; + } else { + oldfunc = th->unblock_function; th->unblock_function = func; } native_mutex_unlock(&th->interrupt_lock); + + return oldfunc; } static void @@ -621,12 +629,15 @@ rb_thread_s_critical(VALUE self) VALUE rb_thread_blocking_region( - VALUE(*func)(rb_thread_t *th, void *), void *data, + rb_blocking_function_t *func, void *data, rb_unblock_function_t *ubf) { VALUE val; rb_thread_t *th = GET_THREAD(); + if (ubf == RB_UBF_DFL) { + ubf = ubf_select; + } BLOCKING_REGION({ val = func(th, data); }, ubf); diff --git a/thread_pthread.ci b/thread_pthread.ci index b28301704a..1b9d1b9c53 100644 --- a/thread_pthread.ci +++ b/thread_pthread.ci @@ -310,6 +310,8 @@ ubf_select(rb_thread_t *th) add_signal_thread_list(th); ubf_select_each(th); } +#else +#define ubf_select 0 #endif static void diff --git a/yarvcore.h b/yarvcore.h index b03e7f0fb2..f755e21790 100644 --- a/yarvcore.h +++ b/yarvcore.h @@ -304,8 +304,6 @@ typedef struct rb_iseq_struct rb_iseq_t; #define GetVMPtr(obj, ptr) \ Data_Get_Struct(obj, rb_vm_t, ptr) -struct rb_thread_struct; - typedef struct rb_vm_struct { VALUE self; @@ -379,12 +377,10 @@ struct rb_vm_tag { struct rb_vm_tag *prev; }; -typedef void rb_unblock_function_t(struct rb_thread_struct *); - #define RUBY_VM_VALUE_CACHE_SIZE 0x1000 #define USE_VALUE_CACHE 1 -typedef struct rb_thread_struct +struct rb_thread_struct { VALUE self; rb_vm_t *vm; @@ -459,7 +455,7 @@ typedef struct rb_thread_struct /* misc */ int method_missing_reason; int abort_on_exception; -} rb_thread_t; +}; /** node -> yarv instruction sequence object */ VALUE rb_iseq_compile(VALUE self, NODE *node); -- cgit v1.2.3