mirror of
https://github.com/ruby/ruby.git
synced 2025-09-19 18:43:59 +02:00
* eval.c (rb_add_threadswitch_hook): wrapper for unofficial APIs
in Mac OS X port. the use of them is strongly discouraged. * eval.c (rb_remove_threadswitch_hook): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@29326 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3a412f2805
commit
f5cbe886b6
9 changed files with 281 additions and 3 deletions
148
ext/-test-/threadswitch/threadswitch_hook.c
Normal file
148
ext/-test-/threadswitch/threadswitch_hook.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
#include <ruby.h>
|
||||
#include <node.h>
|
||||
|
||||
/* copied from eval.c */
|
||||
static const char *
|
||||
get_event_name(rb_event_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case RUBY_EVENT_LINE:
|
||||
return "line";
|
||||
case RUBY_EVENT_CLASS:
|
||||
return "class";
|
||||
case RUBY_EVENT_END:
|
||||
return "end";
|
||||
case RUBY_EVENT_CALL:
|
||||
return "call";
|
||||
case RUBY_EVENT_RETURN:
|
||||
return "return";
|
||||
case RUBY_EVENT_C_CALL:
|
||||
return "c-call";
|
||||
case RUBY_EVENT_C_RETURN:
|
||||
return "c-return";
|
||||
case RUBY_EVENT_RAISE:
|
||||
return "raise";
|
||||
case RUBY_EVENT_THREAD_INIT:
|
||||
return "thread-init";
|
||||
case RUBY_EVENT_THREAD_FREE:
|
||||
return "thread-free";
|
||||
case RUBY_EVENT_THREAD_SAVE:
|
||||
return "thread-save";
|
||||
case RUBY_EVENT_THREAD_RESTORE:
|
||||
return "thread-restore";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE event_callback;
|
||||
|
||||
static void
|
||||
event_hook(event, node, obj, mid, klass)
|
||||
rb_event_t event;
|
||||
NODE *node;
|
||||
VALUE obj;
|
||||
ID mid;
|
||||
VALUE klass;
|
||||
{
|
||||
VALUE block = rb_thread_local_aref(rb_curr_thread->thread, event_callback);
|
||||
if (!NIL_P(block)) {
|
||||
VALUE args = rb_ary_new();
|
||||
rb_ary_push(args, rb_str_new2(get_event_name(event)));
|
||||
rb_ary_push(args, obj);
|
||||
rb_ary_push(args, ID2SYM(mid));
|
||||
rb_ary_push(args, klass);
|
||||
rb_proc_call(block, args);
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
add_event_hook(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
rb_add_event_hook(event_hook, RUBY_EVENT_ALL);
|
||||
return obj;
|
||||
}
|
||||
|
||||
#ifdef RUBY_ENABLE_MACOSX_UNOFFICIAL_THREADSWITCH
|
||||
#define get_threadswitch_event_name(thevent) get_event_name((thevent) << RUBY_THREADSWITCH_SHIFT)
|
||||
|
||||
static void
|
||||
threadswitch_event_hook(event, thread)
|
||||
rb_threadswitch_event_t event;
|
||||
VALUE thread;
|
||||
{
|
||||
VALUE block = rb_thread_local_aref(rb_curr_thread->thread, event_callback);
|
||||
if (!NIL_P(block)) {
|
||||
VALUE args = rb_ary_new();
|
||||
rb_ary_push(args, rb_str_new2(get_threadswitch_event_name(event)));
|
||||
rb_ary_push(args, thread);
|
||||
rb_proc_call(block, args);
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE rb_cThreadSwitchHook;
|
||||
|
||||
static VALUE
|
||||
threadswitch_add_event_hook(klass)
|
||||
VALUE klass;
|
||||
{
|
||||
void *handle = rb_add_threadswitch_hook(threadswitch_event_hook);
|
||||
return Data_Wrap_Struct(klass, 0, rb_remove_threadswitch_hook, handle);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
threadswitch_remove_event_hook(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
void *handle = DATA_PTR(obj);
|
||||
DATA_PTR(obj) = 0;
|
||||
if (handle) {
|
||||
rb_remove_threadswitch_hook(handle);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
restore_hook(arg)
|
||||
VALUE arg;
|
||||
{
|
||||
VALUE *save = (VALUE *)arg;
|
||||
threadswitch_remove_event_hook(save[0]);
|
||||
rb_thread_local_aset(rb_curr_thread->thread, event_callback, save[1]);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
threadswitch_hook(klass)
|
||||
VALUE klass;
|
||||
{
|
||||
VALUE save[2];
|
||||
save[1] = rb_thread_local_aref(rb_curr_thread->thread, event_callback);
|
||||
rb_thread_local_aset(rb_curr_thread->thread, event_callback, rb_block_proc());
|
||||
save[0] = threadswitch_add_event_hook(klass);
|
||||
return rb_ensure(rb_yield, save[0], restore_hook, (VALUE)save);
|
||||
}
|
||||
|
||||
static void
|
||||
Init_threadswitch_hook(mEventHook)
|
||||
VALUE mEventHook;
|
||||
{
|
||||
rb_cThreadSwitchHook = rb_define_class_under(mEventHook, "ThreadSwitch", rb_cObject);
|
||||
rb_define_singleton_method(rb_cThreadSwitchHook, "add", threadswitch_add_event_hook, 0);
|
||||
rb_define_singleton_method(rb_cThreadSwitchHook, "hook", threadswitch_hook, 0);
|
||||
rb_define_method(rb_cThreadSwitchHook, "remove", threadswitch_remove_event_hook, 0);
|
||||
}
|
||||
#else
|
||||
#define Init_threadswitch_hook(mEventHook) (void)(mEventHook)
|
||||
#endif
|
||||
|
||||
void
|
||||
Init_event_hook()
|
||||
{
|
||||
VALUE mEventHook = rb_define_module("EventHook");
|
||||
|
||||
event_callback = rb_intern("rb_event_callback");
|
||||
rb_define_module_function(mEventHook, "hook", add_event_hook, 0);
|
||||
Init_threadswitch_hook(mEventHook);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue