summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--intern.h7
-rw-r--r--thread.c25
-rw-r--r--thread_pthread.ci2
-rw-r--r--yarvcore.h8
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 <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 (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>
* 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);