summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--eval.c103
2 files changed, 84 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 3e81196dd8..7479d1507e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/eval.c b/eval.c
index 00f180d70b..70cb068858 100644
--- a/eval.c
+++ b/eval.c
@@ -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;