Feature #9632 » 0002-speedup-IO-close-with-many-living-threads.patch
| thread.c | ||
|---|---|---|
| 
         int state; 
   | 
||
| 
         th->waiting_fd = fd; 
   | 
||
| 
         list_add(&th->vm->waitfd_threads, &th->waitfd_node); 
   | 
||
| 
         TH_PUSH_TAG(th); 
   | 
||
| 
         if ((state = EXEC_TAG()) == 0) { 
   | 
||
| ... | ... | |
| 
         /* clear waiting_fd anytime */ 
   | 
||
| 
         th->waiting_fd = -1; 
   | 
||
| 
         list_del(&th->waitfd_node); 
   | 
||
| 
         if (state) { 
   | 
||
| 
     	JUMP_TAG(state); 
   | 
||
| ... | ... | |
| 
         return 1; 
   | 
||
| 
     } 
   | 
||
| 
     static int 
   | 
||
| 
     thread_fd_close_i(rb_thread_t *th, void *fdp) 
   | 
||
| 
     { 
   | 
||
| 
         int *fd = fdp; 
   | 
||
| 
         if (th->waiting_fd == *fd) { 
   | 
||
| 
     	VALUE err = th->vm->special_exceptions[ruby_error_closed_stream]; 
   | 
||
| 
     	rb_threadptr_pending_interrupt_enque(th, err); 
   | 
||
| 
     	rb_threadptr_interrupt(th); 
   | 
||
| 
         } 
   | 
||
| 
         return ST_CONTINUE; 
   | 
||
| 
     } 
   | 
||
| 
     void 
   | 
||
| 
     rb_thread_fd_close(int fd) 
   | 
||
| 
     { 
   | 
||
| 
         rb_vm_living_threads_foreach(GET_THREAD()->vm, thread_fd_close_i, &fd); 
   | 
||
| 
         rb_thread_t *th; 
   | 
||
| 
         rb_vm_t *vm = GET_THREAD()->vm; 
   | 
||
| 
         list_for_each(&vm->waitfd_threads, th, waitfd_node) { 
   | 
||
| 
     	if (th->waiting_fd == fd) { 
   | 
||
| 
     	    VALUE err = vm->special_exceptions[ruby_error_closed_stream]; 
   | 
||
| 
     	    rb_threadptr_pending_interrupt_enque(th, err); 
   | 
||
| 
     	    rb_threadptr_interrupt(th); 
   | 
||
| 
     	} 
   | 
||
| 
         } 
   | 
||
| 
     } 
   | 
||
| 
     /* 
   | 
||
| vm_core.h | ||
|---|---|---|
| 
         struct rb_thread_struct *main_thread; 
   | 
||
| 
         struct rb_thread_struct *running_thread; 
   | 
||
| 
         struct list_head waitfd_threads; 
   | 
||
| 
         struct list_head living_threads; 
   | 
||
| 
         size_t living_thread_num; 
   | 
||
| 
         VALUE thgroup_default; 
   | 
||
| ... | ... | |
| 
         int state; 
   | 
||
| 
         int waiting_fd; 
   | 
||
| 
         struct list_node waitfd_node; 
   | 
||
| 
         /* for rb_iterate */ 
   | 
||
| 
         const rb_block_t *passed_block; 
   | 
||
| ... | ... | |
| 
     static inline void 
   | 
||
| 
     rb_vm_living_threads_init(rb_vm_t *vm) 
   | 
||
| 
     { 
   | 
||
| 
         list_head_init(&vm->waitfd_threads); 
   | 
||
| 
         list_head_init(&vm->living_threads); 
   | 
||
| 
         vm->living_thread_num = 0; 
   | 
||
| 
     } 
   | 
||