Bug #13526 » bug13526_dp.patch
| thread.c | ||
|---|---|---|
| 
     #include "thread_sync.c" 
   | 
||
| 
     void 
   | 
||
| 
     bug_13526_debug_print(const char *name, const char *progress, const char *format0, ...) 
   | 
||
| 
     { 
   | 
||
| 
         char format[256]; 
   | 
||
| 
         va_list arg; 
   | 
||
| 
         va_start(arg, format0); 
   | 
||
| 
         snprintf(format, sizeof(format) - 1, "[current th: %08p] %-21s[%-12s] %s\n", GET_THREAD()->self, name, progress, format0); 
   | 
||
| 
         vfprintf(stderr, format, arg); 
   | 
||
| 
         va_end(arg); 
   | 
||
| 
     } 
   | 
||
| 
     void 
   | 
||
| 
     rb_vm_gvl_destroy(rb_vm_t *vm) 
   | 
||
| 
     { 
   | 
||
| 
         gvl_release(vm); 
   | 
||
| ... | ... | |
| 
     terminate_all(rb_vm_t *vm, const rb_thread_t *main_thread) 
   | 
||
| 
     { 
   | 
||
| 
         rb_thread_t *th = 0; 
   | 
||
| 
     bug_13526_debug_print("terminate_all", "terminate", ""); 
   | 
||
| 
         list_for_each(&vm->living_threads, th, vmlt_node) { 
   | 
||
| 
     	if (th != main_thread) { 
   | 
||
| ... | ... | |
| 
         th->status = THREAD_RUNNABLE; 
   | 
||
| 
         th->to_kill = 1; 
   | 
||
| 
         th->errinfo = INT2FIX(TAG_FATAL); 
   | 
||
| 
     bug_13526_debug_print("rb_threadptr_to_kill", "TAG_FATAL", ""); 
   | 
||
| 
         TH_JUMP_TAG(th, TAG_FATAL); 
   | 
||
| 
     } 
   | 
||
| variable.c | ||
|---|---|---|
| 
     static VALUE rb_const_search(VALUE klass, ID id, int exclude, int recurse, int visibility); 
   | 
||
| 
     static st_table *generic_iv_tbl; 
   | 
||
| 
     static st_table *generic_iv_tbl_compat; 
   | 
||
| 
     void bug_13526_debug_print(const char *name, const char *progress, const char *format0, ...); 
   | 
||
| 
     /* per-object */ 
   | 
||
| 
     struct gen_ivtbl { 
   | 
||
| ... | ... | |
| 
     	list_for_each_safe(&state->waitq.head, cur, nxt, waitq.node) { 
   | 
||
| 
     	    VALUE th = cur->thread; 
   | 
||
| 
     bug_13526_debug_print("rb_autoload_reset", "wakeup", "waitq: %08p", &cur->waitq.node); 
   | 
||
| 
     	    cur->thread = Qfalse; 
   | 
||
| 
     	    list_del(&cur->waitq.node); 
   | 
||
| ... | ... | |
| 
         state.mod = mod; 
   | 
||
| 
         state.id = id; 
   | 
||
| 
         state.thread = rb_thread_current(); 
   | 
||
| 
     bug_13526_debug_print("rb_autoload_load", "init state", "ele  : %08p load: %08p", ele, load); 
   | 
||
| 
         if (!ele->state) { 
   | 
||
| 
     	ele->state = &state; 
   | 
||
| ... | ... | |
| 
     	return Qfalse; 
   | 
||
| 
         } 
   | 
||
| 
         else { 
   | 
||
| 
     bug_13526_debug_print("rb_autoload_load", "wait", "waitq: %08p", &state.waitq.node); 
   | 
||
| 
     	list_add_tail(&ele->state->waitq.head, &state.waitq.node); 
   | 
||
| 
     	/* 
   | 
||
| 
     	 * autoload_reset in other thread will resume us and remove us 
   | 
||
| ... | ... | |
| 
     	do { 
   | 
||
| 
     	    rb_thread_sleep_deadly(); 
   | 
||
| 
     	} while (state.thread != Qfalse); 
   | 
||
| 
     bug_13526_debug_print("rb_autoload_load", "unlock", ""); 
   | 
||
| 
         } 
   | 
||
| 
         /* autoload_data_i can be deleted by another thread while require */ 
   | 
||