mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
5374de14e3
commit
f425798fda
5 changed files with 40 additions and 14 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,7 +1,17 @@
|
||||||
Sat Feb 24 18:39:15 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sat Feb 24 18:41:30 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* intern.h (rb_thread_blocking_region): add prototype.
|
||||||
|
|
||||||
* thread.c (rb_thread_debug): added runtime debugging flag.
|
* 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 <aamine@loveruby.net>
|
Sat Feb 24 17:45:48 2007 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
* parse.y (f_arg, opt_f_block_arg): ripper should export VALUE.
|
* parse.y (f_arg, opt_f_block_arg): ripper should export VALUE.
|
||||||
|
|
7
intern.h
7
intern.h
|
@ -536,6 +536,13 @@ VALUE rb_struct_getmember(VALUE, ID);
|
||||||
VALUE rb_struct_iv_get(VALUE, const char*);
|
VALUE rb_struct_iv_get(VALUE, const char*);
|
||||||
VALUE rb_struct_s_members(VALUE);
|
VALUE rb_struct_s_members(VALUE);
|
||||||
VALUE rb_struct_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 */
|
/* time.c */
|
||||||
VALUE rb_time_new(time_t, time_t);
|
VALUE rb_time_new(time_t, time_t);
|
||||||
/* variable.c */
|
/* variable.c */
|
||||||
|
|
25
thread.c
25
thread.c
|
@ -78,7 +78,7 @@ st_delete_wrap(st_table * table, VALUE key)
|
||||||
|
|
||||||
#define THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
|
#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);
|
static void clear_unblock_function(rb_thread_t *th);
|
||||||
|
|
||||||
NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p));
|
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 { \
|
#define BLOCKING_REGION(exec, ubf) do { \
|
||||||
rb_thread_t *__th = GET_THREAD(); \
|
rb_thread_t *__th = GET_THREAD(); \
|
||||||
int __prev_status = __th->status; \
|
int __prev_status = __th->status; \
|
||||||
set_unblock_function(__th, ubf); \
|
rb_unblock_function_t *__oldubf = set_unblock_function(__th, ubf); \
|
||||||
__th->status = THREAD_STOPPED; \
|
__th->status = THREAD_STOPPED; \
|
||||||
|
thread_debug("enter blocking region (%p)\n", __th); \
|
||||||
GVL_UNLOCK_BEGIN(); {\
|
GVL_UNLOCK_BEGIN(); {\
|
||||||
exec; \
|
exec; \
|
||||||
} \
|
} \
|
||||||
GVL_UNLOCK_END(); \
|
GVL_UNLOCK_END(); \
|
||||||
|
thread_debug("leave blocking region (%p)\n", __th); \
|
||||||
remove_signal_thread_list(__th); \
|
remove_signal_thread_list(__th); \
|
||||||
clear_unblock_function(__th); \
|
set_unblock_function(__th, __oldubf); \
|
||||||
if (__th->status == THREAD_STOPPED) { \
|
if (__th->status == THREAD_STOPPED) { \
|
||||||
__th->status = __prev_status; \
|
__th->status = __prev_status; \
|
||||||
} \
|
} \
|
||||||
|
@ -185,20 +187,26 @@ rb_thread_debug(const char *fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static rb_unblock_function_t *
|
||||||
set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func)
|
set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func)
|
||||||
{
|
{
|
||||||
|
rb_unblock_function_t *oldfunc;
|
||||||
|
int interrupted;
|
||||||
|
|
||||||
check_ints:
|
check_ints:
|
||||||
RUBY_VM_CHECK_INTS(); /* check signal or so */
|
RUBY_VM_CHECK_INTS(); /* check signal or so */
|
||||||
native_mutex_lock(&th->interrupt_lock);
|
native_mutex_lock(&th->interrupt_lock);
|
||||||
if (th->interrupt_flag) {
|
if (th->interrupt_flag) {
|
||||||
native_mutex_unlock(&th->interrupt_lock);
|
native_mutex_unlock(&th->interrupt_lock);
|
||||||
goto check_ints;
|
goto check_ints;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
oldfunc = th->unblock_function;
|
||||||
th->unblock_function = func;
|
th->unblock_function = func;
|
||||||
}
|
}
|
||||||
native_mutex_unlock(&th->interrupt_lock);
|
native_mutex_unlock(&th->interrupt_lock);
|
||||||
|
|
||||||
|
return oldfunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -621,12 +629,15 @@ rb_thread_s_critical(VALUE self)
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_thread_blocking_region(
|
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)
|
rb_unblock_function_t *ubf)
|
||||||
{
|
{
|
||||||
VALUE val;
|
VALUE val;
|
||||||
rb_thread_t *th = GET_THREAD();
|
rb_thread_t *th = GET_THREAD();
|
||||||
|
|
||||||
|
if (ubf == RB_UBF_DFL) {
|
||||||
|
ubf = ubf_select;
|
||||||
|
}
|
||||||
BLOCKING_REGION({
|
BLOCKING_REGION({
|
||||||
val = func(th, data);
|
val = func(th, data);
|
||||||
}, ubf);
|
}, ubf);
|
||||||
|
|
|
@ -310,6 +310,8 @@ ubf_select(rb_thread_t *th)
|
||||||
add_signal_thread_list(th);
|
add_signal_thread_list(th);
|
||||||
ubf_select_each(th);
|
ubf_select_each(th);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#define ubf_select 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -304,8 +304,6 @@ typedef struct rb_iseq_struct rb_iseq_t;
|
||||||
#define GetVMPtr(obj, ptr) \
|
#define GetVMPtr(obj, ptr) \
|
||||||
Data_Get_Struct(obj, rb_vm_t, ptr)
|
Data_Get_Struct(obj, rb_vm_t, ptr)
|
||||||
|
|
||||||
struct rb_thread_struct;
|
|
||||||
|
|
||||||
typedef struct rb_vm_struct {
|
typedef struct rb_vm_struct {
|
||||||
VALUE self;
|
VALUE self;
|
||||||
|
|
||||||
|
@ -379,12 +377,10 @@ struct rb_vm_tag {
|
||||||
struct rb_vm_tag *prev;
|
struct rb_vm_tag *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void rb_unblock_function_t(struct rb_thread_struct *);
|
|
||||||
|
|
||||||
#define RUBY_VM_VALUE_CACHE_SIZE 0x1000
|
#define RUBY_VM_VALUE_CACHE_SIZE 0x1000
|
||||||
#define USE_VALUE_CACHE 1
|
#define USE_VALUE_CACHE 1
|
||||||
|
|
||||||
typedef struct rb_thread_struct
|
struct rb_thread_struct
|
||||||
{
|
{
|
||||||
VALUE self;
|
VALUE self;
|
||||||
rb_vm_t *vm;
|
rb_vm_t *vm;
|
||||||
|
@ -459,7 +455,7 @@ typedef struct rb_thread_struct
|
||||||
/* misc */
|
/* misc */
|
||||||
int method_missing_reason;
|
int method_missing_reason;
|
||||||
int abort_on_exception;
|
int abort_on_exception;
|
||||||
} rb_thread_t;
|
};
|
||||||
|
|
||||||
/** node -> yarv instruction sequence object */
|
/** node -> yarv instruction sequence object */
|
||||||
VALUE rb_iseq_compile(VALUE self, NODE *node);
|
VALUE rb_iseq_compile(VALUE self, NODE *node);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue