Created
April 19, 2009 15:50
-
-
Save stephencelis/98109 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=== ruby.h | |
================================================================== | |
--- ruby.h (/trunk) (revision 16) | |
+++ ruby.h (/branches/thread-hooks) (revision 16) | |
@@ -724,6 +724,19 @@ | |
void ruby_native_thread_kill _((int)); | |
#endif | |
+ | |
+typedef unsigned int rb_threadswitch_event_t; | |
+ | |
+#define RUBY_THREADSWITCH_INIT 0x01 | |
+#define RUBY_THREADSWITCH_FREE 0x02 | |
+#define RUBY_THREADSWITCH_SAVE 0x04 | |
+#define RUBY_THREADSWITCH_RESTORE 0x08 | |
+ | |
+typedef void (*rb_threadswitch_hook_func_t) _((rb_threadswitch_event_t,VALUE)); | |
+ | |
+void *rb_add_threadswitch_hook _((rb_threadswitch_hook_func_t func)); | |
+void rb_remove_threadswitch_hook _((void *handle)); | |
+ | |
#if defined(__cplusplus) | |
#if 0 | |
{ /* satisfy cc-mode */ | |
=== eval.c | |
================================================================== | |
--- eval.c (/trunk) (revision 16) | |
+++ eval.c (/branches/thread-hooks) (revision 16) | |
@@ -227,6 +227,25 @@ | |
#include <sys/stat.h> | |
+ | |
+typedef struct threadswitch_hook { | |
+ rb_threadswitch_hook_func_t func; | |
+ struct threadswitch_hook *next; | |
+} rb_threadswitch_hook_t; | |
+ | |
+static rb_threadswitch_hook_t *threadswitch_hooks; | |
+ | |
+#define EXEC_THREADSWITCH_HOOK(event, thread) \ | |
+ do { \ | |
+ rb_threadswitch_hook_t *hook = threadswitch_hooks; \ | |
+ \ | |
+ while (hook) { \ | |
+ (*hook->func)(event, thread); \ | |
+ hook = hook->next; \ | |
+ } \ | |
+ } while (0) | |
+ | |
+ | |
VALUE rb_cProc; | |
VALUE rb_cBinding; | |
static VALUE proc_invoke _((VALUE,VALUE,VALUE,VALUE)); | |
@@ -10131,6 +10150,8 @@ | |
thread_free(th) | |
rb_thread_t th; | |
{ | |
+ EXEC_THREADSWITCH_HOOK(RUBY_THREADSWITCH_FREE,th->thread); | |
+ | |
if (th->stk_ptr) free(th->stk_ptr); | |
th->stk_ptr = 0; | |
#ifdef __ia64__ | |
@@ -10181,6 +10202,8 @@ | |
VALUE *pos; | |
int len; | |
static VALUE tval; | |
+ | |
+ EXEC_THREADSWITCH_HOOK(RUBY_THREADSWITCH_SAVE,th->thread); | |
len = ruby_stack_length(&pos); | |
th->stk_len = 0; | |
@@ -10313,6 +10336,8 @@ | |
#define STACK_PAD_SIZE 1024 | |
volatile VALUE space[STACK_PAD_SIZE], *sp = space; | |
+ EXEC_THREADSWITCH_HOOK(RUBY_THREADSWITCH_RESTORE,th->thread); | |
+ | |
#if !STACK_GROW_DIRECTION | |
if (space < rb_gc_stack_start) { | |
/* Stack grows downward */ | |
@@ -10452,6 +10477,41 @@ | |
rb_thread_main_jump(e, RESTORE_RAISE); | |
} | |
+void * | |
+rb_add_threadswitch_hook(func) | |
+ rb_threadswitch_hook_func_t func; | |
+{ | |
+ rb_threadswitch_hook_t *hook; | |
+ rb_thread_t th; | |
+ | |
+ hook = ALLOC(rb_threadswitch_hook_t); | |
+ hook->func = func; | |
+ hook->next = threadswitch_hooks; | |
+ threadswitch_hooks = hook; | |
+ | |
+ FOREACH_THREAD(th) { | |
+ (*func)(RUBY_THREADSWITCH_INIT, th->thread); | |
+ } END_FOREACH(th); | |
+ | |
+ return hook; | |
+} | |
+ | |
+void | |
+rb_remove_threadswitch_hook(handle) | |
+ void *handle; | |
+{ | |
+ rb_threadswitch_hook_t **hook_p, *hook; | |
+ | |
+ for (hook_p = &threadswitch_hooks; *hook_p; hook_p = &hook->next) { | |
+ hook = *hook_p; | |
+ if (hook == (rb_threadswitch_hook_t*)handle) { | |
+ *hook_p = hook->next; | |
+ xfree(hook); | |
+ return; | |
+ } | |
+ } | |
+} | |
+ | |
static void | |
copy_fds(dst, src, max) | |
fd_set *dst, *src; | |
@@ -11631,6 +11691,8 @@ | |
THREAD_ALLOC(th); | |
th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, th); | |
+ EXEC_THREADSWITCH_HOOK(RUBY_THREADSWITCH_INIT,th->thread); | |
+ | |
for (vars = th->dyna_vars; vars; vars = vars->next) { | |
if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break; | |
FL_SET(vars, DVAR_DONT_RECYCLE); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment