diff options
author | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-28 08:30:51 +0000 |
---|---|---|
committer | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-28 08:30:51 +0000 |
commit | b8a1e36201d3965b3f7b87fe1fa1cf55e00ce045 (patch) | |
tree | 8d485a06dea6c22647555c684f0078896042dee2 /thread.c | |
parent | fc57f2bfdbc6c34289bd3143a7cd5e948ddded9b (diff) |
* 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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37930 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 23 |
1 files changed, 13 insertions, 10 deletions
@@ -342,6 +342,7 @@ typedef struct rb_mutex_struct 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 @@ VALUE 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 @@ rb_mutex_unlock(VALUE self) 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 @@ mutex_sleep(int argc, VALUE *argv, VALUE self) { 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 @@ rb_mutex_synchronize_m(VALUE self, VALUE args) 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 */ |