Hi,

At Thu, 16 May 2002 14:26:39 +0900,
ts wrote:
>  After the signal, ruby must give the control to the current thread (the
>  thread which has received the signal) because this thread need to test if
>  some others signals are pending and it must restore the old value for the
>  main thread.

I read it and noticed rb_thread_schedule() is unnecessary to
change.

Refined patch.


Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.294 diff -u -2 -p -r1.294 eval.c --- eval.c 2002/05/16 05:53:14 1.294 +++ eval.c 2002/05/16 06:33:54 @@ -1426,26 +1426,4 @@ rb_eval_cmd(cmd, arg, tcheck) 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; @@ -7258,4 +7236,84 @@ struct thread { #define END_FOREACH(x) END_FOREACH_FROM(curr_thread,x) +struct thread_status_t { + char *file; + int line; + + 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)->file = (src)->file, \ + (dst)->line = (src)->line, \ + \ + (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 \ +) + +static void rb_thread_ready _((rb_thread_t)); + +static VALUE +rb_trap_eval(cmd, sig) + VALUE cmd; + int sig; +{ + int state; + VALUE val; /* OK */ + 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(); + } + + return val; +} + static const char * thread_status_name(status) @@ -8849,5 +8907,4 @@ rb_thread_trap_eval(cmd, sig) } } - rb_thread_ready(main_thread); th_cmd = cmd; th_sig = sig;
-- Nobu Nakada