ruby-changes:26526
From: ko1 <ko1@a...>
Date: Sun, 23 Dec 2012 19:19:12 +0900 (JST)
Subject: [ruby-changes:26526] ko1:r38577 (trunk): * thread.c: rename methods:
ko1 2012-12-23 19:18:58 +0900 (Sun, 23 Dec 2012) New Revision: 38577 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38577 Log: * thread.c: rename methods: from Thread.async_interrupt_timing to Thread.handle_interrupt, from Thread.async_interrupted? to Thread.pending_interrupt?. Also rename option from `defer' to `never'. [ruby-core:51074] [ruby-trunk - Feature #6762] * vm_core.c, thread.c: rename functions and data structure `async_errinfo' to `pending_interrupt'. * thread.c: add global variables sym_immediate, sym_on_blocking and sym_never. * cont.c, process.c, vm.c, signal.c: ditto. * lib/sync.rb, lib/thread.rb: catch up this renaming. * test/ruby/test_thread.rb: ditto. Modified files: trunk/ChangeLog trunk/cont.c trunk/lib/sync.rb trunk/lib/thread.rb trunk/process.c trunk/signal.c trunk/test/ruby/test_thread.rb trunk/thread.c trunk/vm.c trunk/vm_core.h Index: ChangeLog =================================================================== --- ChangeLog (revision 38576) +++ ChangeLog (revision 38577) @@ -1,3 +1,23 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Dec 23 19:09:16 2012 Koichi Sasada <ko1@a...> + + * thread.c: rename methods: + from Thread.async_interrupt_timing to Thread.handle_interrupt, + from Thread.async_interrupted? to Thread.pending_interrupt?. + Also rename option from `defer' to `never'. + [ruby-core:51074] [ruby-trunk - Feature #6762] + + * vm_core.c, thread.c: rename functions and data structure + `async_errinfo' to `pending_interrupt'. + + * thread.c: add global variables sym_immediate, sym_on_blocking and + sym_never. + + * cont.c, process.c, vm.c, signal.c: ditto. + + * lib/sync.rb, lib/thread.rb: catch up this renaming. + + * test/ruby/test_thread.rb: ditto. + Sun Dec 23 17:57:30 2012 Nobuyoshi Nakada <nobu@r...> * lib/profiler.rb (Profiler__::PROFILE_PROC, print_profile): store Index: vm_core.h =================================================================== --- vm_core.h (revision 38576) +++ vm_core.h (revision 38577) @@ -542,9 +542,9 @@ typedef struct rb_thread_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L542 #endif /* async errinfo queue */ - VALUE async_errinfo_queue; - int async_errinfo_queue_checked; - VALUE async_errinfo_mask_stack; + VALUE pending_interrupt_queue; + int pending_interrupt_queue_checked; + VALUE pending_interrupt_mask_stack; rb_atomic_t interrupt_flag; unsigned long interrupt_mask; @@ -894,16 +894,16 @@ GET_THREAD(void) https://github.com/ruby/ruby/blob/trunk/vm_core.h#L894 enum { TIMER_INTERRUPT_MASK = 0x01, - ASYNC_ERRINFO_INTERRUPT_MASK = 0x02, + PENDING_INTERRUPT_MASK = 0x02, FINALIZER_INTERRUPT_MASK = 0x04, TRAP_INTERRUPT_MASK = 0x08 }; #define RUBY_VM_SET_TIMER_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, TIMER_INTERRUPT_MASK) -#define RUBY_VM_SET_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, ASYNC_ERRINFO_INTERRUPT_MASK) +#define RUBY_VM_SET_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, PENDING_INTERRUPT_MASK) #define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, FINALIZER_INTERRUPT_MASK) #define RUBY_VM_SET_TRAP_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, TRAP_INTERRUPT_MASK) -#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & ~(th)->interrupt_mask & (ASYNC_ERRINFO_INTERRUPT_MASK|TRAP_INTERRUPT_MASK)) +#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & ~(th)->interrupt_mask & (PENDING_INTERRUPT_MASK|TRAP_INTERRUPT_MASK)) #define RUBY_VM_INTERRUPTED_ANY(th) ((th)->interrupt_flag & ~(th)->interrupt_mask) int rb_signal_buff_size(void); @@ -914,16 +914,16 @@ void rb_threadptr_signal_exit(rb_thread_ https://github.com/ruby/ruby/blob/trunk/vm_core.h#L914 void rb_threadptr_execute_interrupts(rb_thread_t *, int); void rb_threadptr_interrupt(rb_thread_t *th); void rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th); -void rb_threadptr_async_errinfo_clear(rb_thread_t *th); -void rb_threadptr_async_errinfo_enque(rb_thread_t *th, VALUE v); -int rb_threadptr_async_errinfo_active_p(rb_thread_t *th); +void rb_threadptr_pending_interrupt_clear(rb_thread_t *th); +void rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v); +int rb_threadptr_pending_interrupt_active_p(rb_thread_t *th); void rb_thread_lock_unlock(rb_thread_lock_t *); void rb_thread_lock_destroy(rb_thread_lock_t *); #define RUBY_VM_CHECK_INTS_BLOCKING(th) do { \ - if (UNLIKELY(!rb_threadptr_async_errinfo_empty_p(th))) { \ - th->async_errinfo_queue_checked = 0; \ + if (UNLIKELY(!rb_threadptr_pending_interrupt_empty_p(th))) { \ + th->pending_interrupt_queue_checked = 0; \ RUBY_VM_SET_INTERRUPT(th); \ rb_threadptr_execute_interrupts(th, 1); \ } \ Index: lib/thread.rb =================================================================== --- lib/thread.rb (revision 38576) +++ lib/thread.rb (revision 38577) @@ -63,9 +63,9 @@ class ConditionVariable https://github.com/ruby/ruby/blob/trunk/lib/thread.rb#L63 # even if no other thread doesn't signal. # def wait(mutex, timeout=nil) - Thread.async_interrupt_timing(StandardError => :defer) do + Thread.handle_interrupt(StandardError => :never) do begin - Thread.async_interrupt_timing(StandardError => :on_blocking) do + Thread.handle_interrupt(StandardError => :on_blocking) do @waiters_mutex.synchronize do @waiters[Thread.current] = true end @@ -84,7 +84,7 @@ class ConditionVariable https://github.com/ruby/ruby/blob/trunk/lib/thread.rb#L84 # Wakes up the first thread in line waiting for this lock. # def signal - Thread.async_interrupt_timing(StandardError => :on_blocking) do + Thread.handle_interrupt(StandardError => :on_blocking) do begin t, _ = @waiters_mutex.synchronize { @waiters.shift } t.run if t @@ -99,7 +99,7 @@ class ConditionVariable https://github.com/ruby/ruby/blob/trunk/lib/thread.rb#L99 # Wakes up all threads waiting for this lock. # def broadcast - Thread.async_interrupt_timing(StandardError => :on_blocking) do + Thread.handle_interrupt(StandardError => :on_blocking) do threads = nil @waiters_mutex.synchronize do threads = @waiters.keys @@ -160,7 +160,7 @@ class Queue https://github.com/ruby/ruby/blob/trunk/lib/thread.rb#L160 # Pushes +obj+ to the queue. # def push(obj) - Thread.async_interrupt_timing(StandardError => :on_blocking) do + Thread.handle_interrupt(StandardError => :on_blocking) do @mutex.synchronize do @que.push obj @cond.signal @@ -184,7 +184,7 @@ class Queue https://github.com/ruby/ruby/blob/trunk/lib/thread.rb#L184 # thread isn't suspended, and an exception is raised. # def pop(non_block=false) - Thread.async_interrupt_timing(StandardError => :on_blocking) do + Thread.handle_interrupt(StandardError => :on_blocking) do @mutex.synchronize do while true if @que.empty? @@ -300,7 +300,7 @@ class SizedQueue < Queue https://github.com/ruby/ruby/blob/trunk/lib/thread.rb#L300 # until space becomes available. # def push(obj) - Thread.async_interrupt_timing(RuntimeError => :on_blocking) do + Thread.handle_interrupt(RuntimeError => :on_blocking) do @mutex.synchronize do while true break if @que.length < @max Index: lib/sync.rb =================================================================== --- lib/sync.rb (revision 38576) +++ lib/sync.rb (revision 38577) @@ -135,7 +135,7 @@ module Sync_m https://github.com/ruby/ruby/blob/trunk/lib/sync.rb#L135 def sync_lock(m = EX) return unlock if m == UN - Thread.async_interrupt_timing(StandardError => :on_blocking) do + Thread.handle_interrupt(StandardError => :on_blocking) do while true @sync_mutex.synchronize do begin @@ -227,7 +227,7 @@ module Sync_m https://github.com/ruby/ruby/blob/trunk/lib/sync.rb#L227 end def sync_synchronize(mode = EX) - Thread.async_interrupt_timing(StandardError => :on_blocking) do + Thread.handle_interrupt(StandardError => :on_blocking) do sync_lock(mode) begin yield Index: thread.c =================================================================== --- thread.c (revision 38576) +++ thread.c (revision 38577) @@ -63,13 +63,17 @@ https://github.com/ruby/ruby/blob/trunk/thread.c#L63 VALUE rb_cMutex; VALUE rb_cThreadShield; +static VALUE sym_immediate; +static VALUE sym_on_blocking; +static VALUE sym_never; + static void sleep_timeval(rb_thread_t *th, struct timeval time, int spurious_check); static void sleep_wait_for_interrupt(rb_thread_t *th, double sleepsec, int spurious_check); static void sleep_forever(rb_thread_t *th, int nodeadlock, int spurious_check); static double timeofday(void); static int rb_threadptr_dead(rb_thread_t *th); static void rb_check_deadlock(rb_vm_t *vm); -static int rb_threadptr_async_errinfo_empty_p(rb_thread_t *th); +static int rb_threadptr_pending_interrupt_empty_p(rb_thread_t *th); #define eKillSignal INT2FIX(0) #define eTerminateSignal INT2FIX(1) @@ -344,7 +348,7 @@ terminate_i(st_data_t key, st_data_t val https://github.com/ruby/ruby/blob/trunk/thread.c#L348 if (th != main_thread) { thread_debug("terminate_i: %p\n", (void *)th); - rb_threadptr_async_errinfo_enque(th, eTerminateSignal); + rb_threadptr_pending_interrupt_enque(th, eTerminateSignal); rb_threadptr_interrupt(th); } else { @@ -599,10 +603,10 @@ thread_create_core(VALUE thval, VALUE ar https://github.com/ruby/ruby/blob/trunk/thread.c#L603 th->priority = current_th->priority; th->thgroup = current_th->thgroup; - th->async_errinfo_queue = rb_ary_tmp_new(0); - th->async_errinfo_queue_checked = 0; - th->async_errinfo_mask_stack = rb_ary_dup(current_th->async_errinfo_mask_stack); - RBASIC(th->async_errinfo_mask_stack)->klass = 0; + th->pending_interrupt_queue = rb_ary_tmp_new(0); + th->pending_interrupt_queue_checked = 0; + th->pending_interrupt_mask_stack = rb_ary_dup(current_th->pending_interrupt_mask_stack); + RBASIC(th->pending_interrupt_mask_stack)->klass = 0; th->interrupt_mask = 0; @@ -1418,47 +1422,47 @@ thread_s_pass(VALUE klass) https://github.com/ruby/ruby/blob/trunk/thread.c#L1422 /*****************************************************/ /* - * rb_threadptr_async_errinfo_* - manage async errors queue + * rb_threadptr_pending_interrupt_* - manage asynchronous error queue * * Async events such as an exception throwed by Thread#raise, * Thread#kill and thread termination (after main thread termination) - * will be queued to th->async_errinfo_queue. + * will be queued to th->pending_interrupt_queue. * - clear: clear the queue. * - enque: enque err object into queue. * - deque: deque err object from queue. * - active_p: return 1 if the queue should be checked. * - * All rb_threadptr_async_errinfo_* functions are called by + * All rb_threadptr_pending_interrupt_* functions are called by * a GVL acquired thread, of course. * Note that all "rb_" prefix APIs need GVL to call. */ void -rb_threadptr_async_errinfo_clear(rb_thread_t *th) +rb_threadptr_pending_interrupt_clear(rb_thread_t *th) { - rb_ary_clear(th->async_errinfo_queue); + rb_ary_clear(th->pending_interrupt_queue); } void -rb_threadptr_async_errinfo_enque(rb_thread_t *th, VALUE v) +rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v) { - rb_ary_push(th->async_errinfo_queue, v); - th->async_errinfo_queue_checked = 0; + rb_ary_push(th->pending_interrupt_queue, v); + th->pending_interrupt_queue_checked = 0; } -enum async_interrupt_timing { +enum handle_interrupt_timing { INTERRUPT_NONE, INTERRUPT_IMMEDIATE, INTERRUPT_ON_BLOCKING, - INTERRUPT_DEFER + INTERRUPT_NEVER }; -static enum async_interrupt_timing -rb_threadptr_async_errinfo_check_mask(rb_thread_t *th, VALUE err) +static enum handle_interrupt_timing +rb_threadptr_pending_interrupt_check_mask(rb_thread_t *th, VALUE err) { VALUE mask; - long mask_stack_len = RARRAY_LEN(th->async_errinfo_mask_stack); - VALUE *mask_stack = RARRAY_PTR(th->async_errinfo_mask_stack); + long mask_stack_len = RARRAY_LEN(th->pending_interrupt_mask_stack); + VALUE *mask_stack = RARRAY_PTR(th->pending_interrupt_mask_stack); VALUE ancestors = rb_mod_ancestors(err); /* TODO: GC guard */ long ancestors_len = RARRAY_LEN(ancestors); VALUE *ancestors_ptr = RARRAY_PTR(ancestors); @@ -1473,14 +1477,14 @@ rb_threadptr_async_errinfo_check_mask(rb https://github.com/ruby/ruby/blob/trunk/thread.c#L1477 /* TODO: remove rb_intern() */ if ((sym = rb_hash_aref(mask, klass)) != Qnil) { - if (sym == ID2SYM(rb_intern("immediate"))) { + if (sym == sym_immediate) { return INTERRUPT_IMMEDIATE; } - else if (sym == ID2SYM(rb_intern("on_blocking"))) { + else if (sym == sym_on_blocking) { return INTERRUPT_ON_BLOCKING; } - else if (sym == ID2SYM(rb_intern("defer"))) { - return INTERRUPT_DEFER; + else if (sym == sym_never) { + return INTERRUPT_NEVER; } else { rb_raise(rb_eThreadError, "unknown mask signature"); @@ -1493,17 +1497,17 @@ rb_threadptr_async_errinfo_check_mask(rb https://github.com/ruby/ruby/blob/trunk/thread.c#L1497 } static int -rb_threadptr_async_errinfo_empty_p(rb_thread_t *th) +rb_threadptr_pending_interrupt_empty_p(rb_thread_t *th) { - return RARRAY_LEN(th->async_errinfo_queue) == 0; + return RARRAY_LEN(th->pending_interrupt_queue) == 0; } static int -rb_threadptr_async_errinfo_include_p(rb_thread_t *th, VALUE err) +rb_threadptr_pending_interrupt_include_p(rb_thread_t *th, VALUE err) { int i; - for (i=0; i<RARRAY_LEN(th->async_errinfo_queue); i++) { - VALUE e = RARRAY_PTR(th->async_errinfo_queue)[i]; + for (i=0; i<RARRAY_LEN(th->pending_interrupt_queue); i++) { + VALUE e = RARRAY_PTR(th->pending_interrupt_queue)[i]; if (rb_class_inherited_p(e, err)) { return TRUE; } @@ -1512,15 +1516,15 @@ rb_threadptr_async_errinfo_include_p(rb_ https://github.com/ruby/ruby/blob/trunk/thread.c#L1516 } static VALUE -rb_threadptr_async_errinfo_deque(rb_thread_t *th, enum async_interrupt_timing timing) +rb_threadptr_pending_interrupt_deque(rb_thread_t *th, enum handle_interrupt_timing timing) { -#if 1 /* 1 to enable Thread#async_interrupt_timing, 0 to ignore it */ +#if 1 /* 1 to enable Thread#handle_interrupt, 0 to ignore it */ int i; - for (i=0; i<RARRAY_LEN(th->async_errinfo_queue); i++) { - VALUE err = RARRAY_PTR(th->async_errinfo_queue)[i]; + for (i=0; i<RARRAY_LEN(th->pending_interrupt_queue); i++) { + VALUE err = RARRAY_PTR(th->pending_interrupt_queue)[i]; - enum async_interrupt_timing mask_timing = rb_threadptr_async_errinfo_check_mask(th, CLASS_OF(err)); + enum handle_interrupt_timing mask_timing = rb_threadptr_pending_interrupt_check_mask(th, CLASS_OF(err)); switch (mask_timing) { case INTERRUPT_ON_BLOCKING: @@ -1530,37 +1534,37 @@ rb_threadptr_async_errinfo_deque(rb_thre https://github.com/ruby/ruby/blob/trunk/thread.c#L1534 /* fall through */ case INTERRUPT_NONE: /* default: IMMEDIATE */ case INTERRUPT_IMMEDIATE: - rb_ary_delete_at(th->async_errinfo_queue, i); + rb_ary_delete_at(th->pending_interrupt_queue, i); return err; - case INTERRUPT_DEFER: + case INTERRUPT_NEVER: break; } } - th->async_errinfo_queue_checked = 1; + th->pending_interrupt_queue_checked = 1; return Qundef; #else - VALUE err = rb_ary_shift(th->async_errinfo_queue); - if (rb_threadptr_async_errinfo_empty_p(th)) { - th->async_errinfo_queue_checked = 1; + VALUE err = rb_ary_shift(th->pending_interrupt_queue); + if (rb_threadptr_pending_interrupt_empty_p(th)) { + th->pending_interrupt_queue_checked = 1; } return err; #endif } int -rb_threadptr_async_errinfo_active_p(rb_thread_t *th) +rb_threadptr_pending_interrupt_active_p(rb_thread_t *th) { /* * For optimization, we don't check async errinfo queue * if it nor a thread interrupt mask were not changed * since last check. */ - if (th->async_errinfo_queue_checked) { + if (th->pending_interrupt_queue_checked) { return 0; } - if (rb_threadptr_async_errinfo_empty_p(th)) { + if (rb_threadptr_pending_interrupt_empty_p(th)) { return 0; } @@ -1568,13 +1572,9 @@ rb_threadptr_async_errinfo_active_p(rb_t https://github.com/ruby/ruby/blob/trunk/thread.c#L1572 } static int -async_interrupt_timing_arg_check_i(VALUE key, VALUE val) +handle_interrupt_arg_check_i(VALUE key, VALUE val) { - VALUE immediate = ID2SYM(rb_intern("immediate")); - VALUE on_blocking = ID2SYM(rb_intern("on_blocking")); - VALUE defer = ID2SYM(rb_intern("defer")); - - if (val != immediate && val != on_blocking && val != defer) { + if (val != sym_immediate && val != sym_on_blocking && val != sym_never) { rb_raise(rb_eArgError, "unknown mask signature"); } @@ -1583,20 +1583,20 @@ async_interrupt_timing_arg_check_i(VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L1583 /* * call-seq: - * Thread.async_interrupt_timing(hash) { ... } -> result of the block + * Thread.handle_interrupt(hash) { ... } -> result of the block * - * Thread.Thread#async_interrupt_timing controls async interrupt timing. + * Thread.Thread#handle_interrupt changes async interrupt timing. * - * _async_interrupt_ means asynchronous event and corresponding procedure + * _interrupt_ means asynchronous event and corresponding procedure * by Thread#raise, Thread#kill, signal trap (not supported yet) * and main thread termination (if main thread terminates, then all * other thread will be killed). * * _hash_ has pairs of ExceptionClass and TimingSymbol. TimingSymbol * is one of them: - * - :immediate Invoke async interrupt immediately. - * - :on_blocking Invoke async interrupt while _BlockingOperation_. - * - :defer Defer all async interrupt. + * - :immediate Invoke interrupts immediately. + * - :on_blocking Invoke interrupts while _BlockingOperation_. + * - :never Never invoke all interrupts. * * _BlockingOperation_ means that the operation will block the calling thread, * such as read and write. On CRuby implementation, _BlockingOperation_ is @@ -1605,9 +1605,9 @@ async_interrupt_timing_arg_check_i(VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L1605 * Masked async interrupts are delayed until they are enabled. * This method is similar to sigprocmask(3). * - * TODO (DOC): Thread#async_interrupt_timing is stacked. + * TODO (DOC): Thread#handle_interrupt is stacked. * TODO (DOC): check ancestors. - * TODO (DOC): to prevent all async interrupt, {Object => :defer} works. + * TODO (DOC): to prevent all async interrupt, {Object => :never} works. * * NOTE: Asynchronous interrupts are difficult to use. * If you need to communicate between threads, @@ -1617,16 +1617,16 @@ async_interrupt_timing_arg_check_i(VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L1617 * * # example: Guard from Thread#raise * th = Thread.new do - * Thead.async_interrupt_timing(RuntimeError => :defer) { + * Thead.handle_interrupt(RuntimeError => :never) { * begin * # Thread#raise doesn't async interrupt here. * # You can write resource allocation code safely. - * Thread.async_interrupt_timing(RuntimeError => :immediate) { + * Thread.handle_interrupt(RuntimeError => :immediate) { * # ... * # It is possible to be interrupted by Thread#raise. * } * ensure - * # Thread#raise doesn't async interrupt here. + * # Thread#raise doesn't interrupt here. * # You can write resource dealocation code safely. * end * } @@ -1637,10 +1637,10 @@ async_interrupt_timing_arg_check_i(VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L1637 * * # example: Guard from TimeoutError * require 'timeout' - * Thread.async_interrupt_timing(TimeoutError => :defer) { + * Thread.handle_interrupt(TimeoutError => :never) { * timeout(10){ * # TimeoutError doesn't occur here - * Thread.async_interrupt_timing(TimeoutError => :on_blocking) { + * Thread.handle_interrupt(TimeoutError => :on_blocking) { * # possible to be killed by TimeoutError * # while blocking operation * } @@ -1649,20 +1649,20 @@ async_interrupt_timing_arg_check_i(VALUE https://github.com/ruby/ruby/blob/trunk/thread.c#L1649 * } * * # example: Stack control settings - * Thread.async_interrupt_timing(FooError => :defer) { - * Thread.async_interrupt_timing(BarError = (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/