diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-09-11 15:13:10 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-09-11 15:13:10 +0000 |
commit | 368e015170a6492c6ccfa416c0b6ee5f78261fd9 (patch) | |
tree | a9103c061685f9261bdb08a4ec62982bfd68c006 | |
parent | c47f24027a3473fbdf9510cc300565fb1e6f1db8 (diff) |
* 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
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | eval.c | 103 |
2 files changed, 84 insertions, 24 deletions
@@ -1,3 +1,8 @@ +Thu Sep 12 00:09:32 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net> + + * eval.c (rb_trap_eval): preserve thread status and so on. + [ruby-talk:40337], [ruby-core:00019] + Wed Sep 11 21:25:52 2002 Tanaka Akira <akr@m17n.org> * pp.rb (ARGF.pretty_print): implemented. @@ -1467,28 +1467,6 @@ 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; NODE *node; @@ -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; |