Project

General

Profile

Feature #5788 » patch.diff

Glass_saga (Masaki Matsushita), 12/22/2011 05:35 PM

View differences:

thread.c
native_thread_init_stack(th);
}
static void thread_run_at_exit(rb_thread_t *th);
static int
thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_start)
{
......
th->value = Qnil;
}
thread_run_at_exit(th);
th->status = THREAD_KILLED;
thread_debug("thread end: %p\n", (void *)th);
......
return str;
}
static void
thread_run_at_exit(rb_thread_t *th)
{
int i;
VALUE at_exit;
if(th->at_exit){
at_exit = th->at_exit;
for (i=0; i<RARRAY_LEN(at_exit); i++) {
rb_proc_call(RARRAY_PTR(at_exit)[i], rb_ary_new());
}
}
return;
}
VALUE
rb_thread_define_at_exit(VALUE thread)
{
rb_thread_t *th;
VALUE proc;
if (!rb_block_given_p()) {
rb_raise(rb_eArgError, "called without a block");
}
proc = rb_block_proc();
GetThreadPtr(thread, th);
if (th == th->vm->main_thread) {
rb_set_end_proc(rb_call_end_proc, proc);
} else {
if (th->at_exit) {
rb_ary_push(th->at_exit, proc);
} else {
th->at_exit = rb_ary_new3(1, proc);
}
}
return thread;
}
VALUE
rb_thread_local_aref(VALUE thread, ID id)
{
......
rb_define_method(rb_cThread, "safe_level", rb_thread_safe_level, 0);
rb_define_method(rb_cThread, "group", rb_thread_group, 0);
rb_define_method(rb_cThread, "backtrace", rb_thread_backtrace_m, 0);
rb_define_method(rb_cThread, "at_exit", rb_thread_define_at_exit, 0);
rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);
vm_core.h
/* storage */
st_table *local_storage;
VALUE at_exit;
struct rb_thread_struct *join_list_next;
struct rb_thread_struct *join_list_head;
(1-1/3)