mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
fc57f2bfdb
commit
b8a1e36201
5 changed files with 41 additions and 10 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
Wed Nov 28 16:21:46 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
|
* 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@atdot.net>
|
Wed Nov 28 16:59:12 2012 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* proc.c: remove Proc#== and Proc#eql?.
|
* proc.c: remove Proc#== and Proc#eql?.
|
||||||
|
|
|
@ -278,6 +278,7 @@ VALUE rb_thread_shield_new(void);
|
||||||
VALUE rb_thread_shield_wait(VALUE self);
|
VALUE rb_thread_shield_wait(VALUE self);
|
||||||
VALUE rb_thread_shield_release(VALUE self);
|
VALUE rb_thread_shield_release(VALUE self);
|
||||||
VALUE rb_thread_shield_destroy(VALUE self);
|
VALUE rb_thread_shield_destroy(VALUE self);
|
||||||
|
void rb_mutex_allow_trap(VALUE self, int val);
|
||||||
|
|
||||||
/* thread_pthread.c, thread_win32.c */
|
/* thread_pthread.c, thread_win32.c */
|
||||||
void Init_native_thread(void);
|
void Init_native_thread(void);
|
||||||
|
|
1
io.c
1
io.c
|
@ -1126,6 +1126,7 @@ io_binwrite(VALUE str, const char *ptr, long len, rb_io_t *fptr, int nosync)
|
||||||
fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
|
fptr->wbuf.capa = IO_WBUF_CAPA_MIN;
|
||||||
fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
|
fptr->wbuf.ptr = ALLOC_N(char, fptr->wbuf.capa);
|
||||||
fptr->write_lock = rb_mutex_new();
|
fptr->write_lock = rb_mutex_new();
|
||||||
|
rb_mutex_allow_trap(fptr->write_lock, 1);
|
||||||
}
|
}
|
||||||
if ((!nosync && (fptr->mode & (FMODE_SYNC|FMODE_TTY))) ||
|
if ((!nosync && (fptr->mode & (FMODE_SYNC|FMODE_TTY))) ||
|
||||||
(fptr->wbuf.ptr && fptr->wbuf.capa <= fptr->wbuf.len + len)) {
|
(fptr->wbuf.ptr && fptr->wbuf.capa <= fptr->wbuf.len + len)) {
|
||||||
|
|
|
@ -260,4 +260,17 @@ EOS
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
23
thread.c
23
thread.c
|
@ -342,6 +342,7 @@ typedef struct rb_mutex_struct
|
||||||
struct rb_thread_struct volatile *th;
|
struct rb_thread_struct volatile *th;
|
||||||
int cond_waiting;
|
int cond_waiting;
|
||||||
struct rb_mutex_struct *next_mutex;
|
struct rb_mutex_struct *next_mutex;
|
||||||
|
int allow_trap;
|
||||||
} rb_mutex_t;
|
} rb_mutex_t;
|
||||||
|
|
||||||
static void rb_mutex_abandon_all(rb_mutex_t *mutexes);
|
static void rb_mutex_abandon_all(rb_mutex_t *mutexes);
|
||||||
|
@ -4140,16 +4141,15 @@ VALUE
|
||||||
rb_mutex_lock(VALUE self)
|
rb_mutex_lock(VALUE self)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = GET_THREAD();
|
rb_thread_t *th = GET_THREAD();
|
||||||
|
rb_mutex_t *mutex;
|
||||||
|
GetMutexPtr(self, mutex);
|
||||||
|
|
||||||
/* When running trap handler */
|
/* 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");
|
rb_raise(rb_eThreadError, "can't be called from trap context");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb_mutex_trylock(self) == Qfalse) {
|
if (rb_mutex_trylock(self) == Qfalse) {
|
||||||
rb_mutex_t *mutex;
|
|
||||||
GetMutexPtr(self, mutex);
|
|
||||||
|
|
||||||
if (mutex->th == GET_THREAD()) {
|
if (mutex->th == GET_THREAD()) {
|
||||||
rb_raise(rb_eThreadError, "deadlock; recursive locking");
|
rb_raise(rb_eThreadError, "deadlock; recursive locking");
|
||||||
}
|
}
|
||||||
|
@ -4254,7 +4254,7 @@ rb_mutex_unlock(VALUE self)
|
||||||
GetMutexPtr(self, mutex);
|
GetMutexPtr(self, mutex);
|
||||||
|
|
||||||
/* When running trap handler */
|
/* 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");
|
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;
|
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);
|
rb_scan_args(argc, argv, "01", &timeout);
|
||||||
return rb_mutex_sleep(self, 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);
|
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
|
* Document-class: ThreadShield
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue