ruby-changes:25873
From: kosaki <ko1@a...>
Date: Wed, 28 Nov 2012 17:31:04 +0900 (JST)
Subject: [ruby-changes:25873] kosaki:r37930 (trunk): * thread.c (struct rb_mutex_struct): add allow_trap field.
kosaki 2012-11-28 17:30:51 +0900 (Wed, 28 Nov 2012) New Revision: 37930 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37930 Log: * thread.c (struct rb_mutex_struct): add allow_trap field. * internal.h (rb_mutex_allow_trap): added. * thread.c (rb_mutex_lock, rb_mutex_unlock): check mutex->allow_trap. * thread.c (mutex_sleep): remove trap check because it uses rb_mutex_lock and rb_mutex_unlock internally. * thread.c (rb_mutex_allow_trap): new helper function for the above. * io.c (io_binwrite): mark fptr->write_lock as writable in trap. * test/ruby/test_signal.rb (test_trap_puts): test for the above. Modified files: trunk/ChangeLog trunk/internal.h trunk/io.c trunk/test/ruby/test_signal.rb trunk/thread.c Index: ChangeLog =================================================================== --- ChangeLog (revision 37929) +++ ChangeLog (revision 37930) @@ -1,3 +1,16 @@ +Wed Nov 28 16:21:46 2012 KOSAKI Motohiro <kosaki.motohiro@g...> + + * thread.c (struct rb_mutex_struct): add allow_trap field. + * internal.h (rb_mutex_allow_trap): added. + * thread.c (rb_mutex_lock, rb_mutex_unlock): check mutex->allow_trap. + * thread.c (mutex_sleep): remove trap check because it uses + rb_mutex_lock and rb_mutex_unlock internally. + * thread.c (rb_mutex_allow_trap): new helper function for the above. + + * io.c (io_binwrite): mark fptr->write_lock as writable in trap. + + * test/ruby/test_signal.rb (test_trap_puts): test for the above. + Wed Nov 28 16:59:12 2012 Koichi Sasada <ko1@a...> * proc.c: remove Proc#== and Proc#eql?. Index: io.c =================================================================== --- io.c (revision 37929) +++ io.c (revision 37930) @@ -1126,6 +1126,7 @@ fptr->wbuf.capa = IO_WBUF_CAPA_MIN; fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa); fptr->write_lock = rb_mutex_new(); + rb_mutex_allow_trap(fptr->write_lock, 1); } if ((!nosync && (fptr->mode & (FMODE_SYNC|FMODE_TTY))) || (fptr->wbuf.ptr && fptr->wbuf.capa <= fptr->wbuf.len + len)) { Index: thread.c =================================================================== --- thread.c (revision 37929) +++ thread.c (revision 37930) @@ -342,6 +342,7 @@ struct rb_thread_struct volatile *th; int cond_waiting; struct rb_mutex_struct *next_mutex; + int allow_trap; } rb_mutex_t; static void rb_mutex_abandon_all(rb_mutex_t *mutexes); @@ -4140,16 +4141,15 @@ rb_mutex_lock(VALUE self) { rb_thread_t *th = GET_THREAD(); + rb_mutex_t *mutex; + GetMutexPtr(self, mutex); /* When running trap handler */ - if (th->interrupt_mask & TRAP_INTERRUPT_MASK) { + if (!mutex->allow_trap && th->interrupt_mask & TRAP_INTERRUPT_MASK) { rb_raise(rb_eThreadError, "can't be called from trap context"); } if (rb_mutex_trylock(self) == Qfalse) { - rb_mutex_t *mutex; - GetMutexPtr(self, mutex); - if (mutex->th == GET_THREAD()) { rb_raise(rb_eThreadError, "deadlock; recursive locking"); } @@ -4254,7 +4254,7 @@ GetMutexPtr(self, mutex); /* When running trap handler */ - if (GET_THREAD()->interrupt_mask & TRAP_INTERRUPT_MASK) { + if (!mutex->allow_trap && GET_THREAD()->interrupt_mask & TRAP_INTERRUPT_MASK) { rb_raise(rb_eThreadError, "can't be called from trap context"); } @@ -4326,11 +4326,6 @@ { VALUE timeout; - /* When running trap handler */ - if (GET_THREAD()->interrupt_mask & TRAP_INTERRUPT_MASK) { - rb_raise(rb_eThreadError, "can't be called from trap context"); - } - rb_scan_args(argc, argv, "01", &timeout); return rb_mutex_sleep(self, timeout); } @@ -4367,6 +4362,14 @@ return rb_mutex_synchronize(self, rb_yield, Qnil); } +void rb_mutex_allow_trap(VALUE self, int val) +{ + rb_mutex_t *m; + GetMutexPtr(self, m); + + m->allow_trap = val; +} + /* * Document-class: ThreadShield */ Index: internal.h =================================================================== --- internal.h (revision 37929) +++ internal.h (revision 37930) @@ -278,6 +278,7 @@ VALUE rb_thread_shield_wait(VALUE self); VALUE rb_thread_shield_release(VALUE self); VALUE rb_thread_shield_destroy(VALUE self); +void rb_mutex_allow_trap(VALUE self, int val); /* thread_pthread.c, thread_win32.c */ void Init_native_thread(void); Index: test/ruby/test_signal.rb =================================================================== --- test/ruby/test_signal.rb (revision 37929) +++ test/ruby/test_signal.rb (revision 37930) @@ -260,4 +260,17 @@ end end end + + def test_trap_puts + assert_in_out_err([], <<-INPUT, ["a"*10000], []) + Signal.trap(:INT) { + # for enable internal io mutex + sync = false + # larger than internal io buffer + print "a"*10000 + } + Process.kill :INT, $$ + sleep 0.1 + INPUT + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/