From 368e015170a6492c6ccfa416c0b6ee5f78261fd9 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 11 Sep 2002 15:13:10 +0000 Subject: * eval.c (rb_trap_eval): preserve thread status and so on. [ruby-talk:40337], [ruby-core:00019] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2852 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- eval.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 24 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index 00f180d70b..70cb068858 100644 --- a/eval.c +++ b/eval.c @@ -1466,28 +1466,6 @@ rb_eval_cmd(cmd, arg, tcheck) return val; } -static VALUE -rb_trap_eval(cmd, sig) - VALUE cmd; - int sig; -{ - int state; - VALUE val; /* OK */ - - PUSH_TAG(PROT_NONE); - PUSH_ITER(ITER_NOT); - if ((state = EXEC_TAG()) == 0) { - val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), 0); - } - POP_ITER(); - POP_TAG(); - if (state) { - rb_trap_immediate = 0; - JUMP_TAG(state); - } - return val; -} - static VALUE superclass(self, node) VALUE self; @@ -7363,6 +7341,85 @@ struct thread { #define FOREACH_THREAD(x) FOREACH_THREAD_FROM(curr_thread,x) #define END_FOREACH(x) END_FOREACH_FROM(curr_thread,x) +struct thread_status_t { + NODE *node; + + int tracing; + VALUE errinfo; + VALUE last_status; + VALUE last_line; + VALUE last_match; + + int safe; + + enum thread_status status; + int wait_for; + int fd; + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + int select_value; + double delay; + rb_thread_t join; +}; + +#define THREAD_COPY_STATUS(src, dst) (void)( \ + (dst)->node = (src)->node, \ + \ + (dst)->tracing = (src)->tracing, \ + (dst)->errinfo = (src)->errinfo, \ + (dst)->last_status = (src)->last_status, \ + (dst)->last_line = (src)->last_line, \ + (dst)->last_match = (src)->last_match, \ + \ + (dst)->safe = (src)->safe, \ + \ + (dst)->status = (src)->status, \ + (dst)->wait_for = (src)->wait_for, \ + (dst)->fd = (src)->fd, \ + (dst)->readfds = (src)->readfds, \ + (dst)->writefds = (src)->writefds, \ + (dst)->exceptfds = (src)->exceptfds, \ + (dst)->select_value = (src)->select_value, \ + (dst)->delay = (src)->delay, \ + (dst)->join = (src)->join, \ + 0) + +static void rb_thread_ready _((rb_thread_t)); + +static VALUE +rb_trap_eval(cmd, sig) + VALUE cmd; + int sig; +{ + int state; + VALUE val; /* OK */ + volatile struct thread_status_t save; + + THREAD_COPY_STATUS(curr_thread, &save); + rb_thread_ready(curr_thread); + PUSH_TAG(PROT_NONE); + PUSH_ITER(ITER_NOT); + if ((state = EXEC_TAG()) == 0) { + val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), 0); + } + POP_ITER(); + POP_TAG(); + THREAD_COPY_STATUS(&save, curr_thread); + + if (state) { + rb_trap_immediate = 0; + JUMP_TAG(state); + } + + if (curr_thread->status == THREAD_STOPPED) { + rb_thread_schedule(); + } + errno = EINTR; + + return val; +} + static const char * thread_status_name(status) enum thread_status status; @@ -7599,7 +7656,6 @@ thread_switch(n) break; case RESTORE_TRAP: rb_trap_eval(th_cmd, th_sig); - errno = EINTR; break; case RESTORE_RAISE: ruby_frame->last_func = 0; @@ -8961,7 +9017,6 @@ rb_thread_trap_eval(cmd, sig) return; } } - rb_thread_ready(main_thread); th_cmd = cmd; th_sig = sig; curr_thread = main_thread; -- cgit v1.2.3