[#21508] eval BEGIN/END at runtime — "NAKAMURA, Hiroshi" <nakahiro@...>

なひです。

15 messages 2003/10/06

[#21616] access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...>

永井@知能.九工大です.

44 messages 2003/10/14
[#21643] Re: access ENV on $SAFE==4 — matz@... (Yukihiro Matsumoto) 2003/10/20

まつもと ゆきひろです

[#21646] Re: access ENV on $SAFE==4 — TADA Tadashi <sho@...> 2003/10/20

ただただしです。

[#21656] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/20

永井@知能.九工大です.

[#21695] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/23

永井@知能.九工大です.

[#21696] Re: access ENV on $SAFE==4 — nobu.nakada@... 2003/10/23

なかだです。

[#21697] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/23

永井@知能.九工大です.

[#21698] Re: access ENV on $SAFE==4 — nobu.nakada@... 2003/10/23

なかだです。

[#21704] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/24

永井@知能.九工大です.

[#21712] Re: access ENV on $SAFE==4 — matz@... (Yukihiro Matsumoto) 2003/10/24

まつもと ゆきひろです

[#21713] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/24

永井@知能.九工大です.

[#21715] Re: access ENV on $SAFE==4 — matz@... (Yukihiro Matsumoto) 2003/10/25

まつもと ゆきひろです

[#21718] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/25

永井@知能.九工大です.

[#21720] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/25

永井@知能.九工大です.

[#21721] Re: access ENV on $SAFE==4 — matz@... (Yukihiro Matsumoto) 2003/10/25

まつもと ゆきひろです

[#21723] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/25

永井@知能.九工大です.

[#21727] Re: access ENV on $SAFE==4 — Hidetoshi NAGAI <nagai@...> 2003/10/26

永井@知能.九工大です.

[#21682] ruby-tk hangs when exception is raised — akira yamada <akira@...>

62 messages 2003/10/23
[#21683] Re: ruby-tk hangs when exception is raised — nobu.nakada@... 2003/10/23

なかだです。

[#21685] Re: ruby-tk hangs when exception is raised — akira yamada / やまだあきら <akira@...> 2003/10/23

[#21687] Re: ruby-tk hangs when exception is raised — Hidetoshi NAGAI <nagai@...> 2003/10/23

永井@知能.九工大です.

[#21688] Re: ruby-tk hangs when exception is raised — akira yamada / やまだあきら <akira@...> 2003/10/23

[#21691] Re: ruby-tk hangs when exception is raised — Hidetoshi NAGAI <nagai@...> 2003/10/23

永井@知能.九工大です.

[#21693] Re: ruby-tk hangs when exception is raised — akira yamada / やまだあきら <akira@...> 2003/10/23

[#21694] Re: ruby-tk hangs when exception is raised — Hidetoshi NAGAI <nagai@...> 2003/10/23

永井@知能.九工大です.

[#21736] Re: ruby-tk hangs when exception is raised — Hidetoshi NAGAI <nagai@...> 2003/10/28

永井@知能.九工大です.

[#21744] Re: ruby-tk hangs when exception is raised — akira yamada / やまだあきら <akira@...> 2003/10/28

[#21797] Re: ruby-tk hangs when exception is raised — Hidetoshi NAGAI <nagai@...> 2003/10/31

永井@知能.九工大です.

[#21801] Re: ruby-tk hangs when exception is raised — Hidetoshi NAGAI <nagai@...> 2003/11/01

永井@知能.九工大です.

[#21825] Re: ruby-tk hangs when exception is raised — Hidetoshi NAGAI <nagai@...> 2003/11/04

永井@知能.九工大です.

[#21833] pthread trouble on tcltklib (Re: ruby-tk hangs when exception is raised) — Hidetoshi NAGAI <nagai@...> 2003/11/05

永井@知能.九工大です.

[#21835] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/05

永井@知能.九工大です.

[#21900] Re: pthread trouble on tcltklib — nobu.nakada@... 2003/11/11

なかだです。

[#21901] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/12

永井@知能.九工大です.

[#21905] Re: pthread trouble on tcltklib — nobu.nakada@... 2003/11/12

なかだです。

[#21908] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/12

永井@知能.九工大です.

[#21914] Re: pthread trouble on tcltklib — nobu.nakada@... 2003/11/12

なかだです。

[#21915] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/12

永井@知能.九工大です.

[#21916] Re: pthread trouble on tcltklib — nobu.nakada@... 2003/11/12

なかだです。

[#21922] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/14

永井@知能.九工大です.

[#21929] Re: pthread trouble on tcltklib — Tietew <tietew-ml-ruby-dev@...> 2003/11/17

[#21930] Re: pthread trouble on tcltklib — nobu.nakada@... 2003/11/17

なかだです。

[#21931] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/17

永井@知能.九工大です.

[#21934] Re: pthread trouble on tcltklib — nobu.nakada@... 2003/11/17

なかだです。

[#21937] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/17

永井@知能.九工大です.

[#21952] Re: pthread trouble on tcltklib — matz@... (Yukihiro Matsumoto) 2003/11/18

まつもと ゆきひろです

[#21957] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/19

永井@知能.九工大です.

[#21958] Re: pthread trouble on tcltklib — Tietew <tietew-ml-ruby-dev@...> 2003/11/19

[#21959] Re: pthread trouble on tcltklib — Hidetoshi NAGAI <nagai@...> 2003/11/19

永井@知能.九工大です.

[#21960] Re: pthread trouble on tcltklib — Tietew <tietew-ml-ruby-dev@...> 2003/11/19

[#21707] drb Hash#each — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

22 messages 2003/10/24
[#21708] Re: drb Hash#each — m_seki@... 2003/10/24

[#21709] Re: drb Hash#each — matz@... (Yukihiro Matsumoto) 2003/10/24

まつもと ゆきひろです

[#21710] Re: drb Hash#each — m_seki@... 2003/10/24

[#21747] ruby 1.8.1 preview1 schedule — matz@... (Yukihiro Matsumoto)

関係者各位、

25 messages 2003/10/29

[ruby-dev:21556] rewinding for Thread

From: nobu.nakada@...
Date: 2003-10-09 03:03:28 UTC
List: ruby-dev #21556
なかだです。

以前、スレッドの中でスレッドを作るというのを繰り返すとstack
level too deepになる、という話があったような気がするので、Proc
を作ってからトップレベルまで巻き戻してブランチするようにしてみ
ました。

* eval.c (TAG_THREAD): to start a new thread.

* eval.c (ruby_init, ruby_options, rb_thread_start_0): start the
  thread in upper environment.

* eval.c (proc_alloc): clone proc object if klass is not Proc or
  created in different thread.

* eval.c (rb_block_pass): call a function with a block.  [new]

* eval.c (rb_f_throw): raise NameError in main thread.

* ruby.h: prototype; rb_block_pass.


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.554
diff -u -2 -p -r1.554 eval.c
--- eval.c	9 Oct 2003 01:51:08 -0000	1.554
+++ eval.c	9 Oct 2003 02:28:12 -0000
@@ -876,4 +877,5 @@ static struct tag *prot_tag;
 #define TAG_THROW	0x7
 #define TAG_FATAL	0x8
+#define TAG_THREAD	0x9
 #define TAG_MASK	0xf
 
@@ -1135,4 +1137,6 @@ void Init_heap _((void));
 void Init_ext _((void));
 
+NORETURN(static void rb_thread_start_1 _((void)));
+
 void
 ruby_init()
@@ -1165,5 +1169,5 @@ ruby_init()
     SCOPE_SET(SCOPE_PRIVATE);
 
-    PUSH_TAG(PROT_NONE);
+    PUSH_TAG(PROT_THREAD);
     if ((state = EXEC_TAG()) == 0) {
 	rb_call_inits();
@@ -1179,4 +1183,7 @@ ruby_init()
 	ALLOW_INTS;
     }
+    else if (state == TAG_THREAD) {
+	rb_thread_start_1();
+    }
     POP_TAG();
     if (state) {
@@ -1291,8 +1298,11 @@ ruby_options(argc, argv)
 
     Init_stack((void*)&state);
-    PUSH_TAG(PROT_NONE);
+    PUSH_TAG(PROT_THREAD);
     if ((state = EXEC_TAG()) == 0) {
 	ruby_process_options(argc, argv);
     }
+    else if (state == TAG_THREAD) {
+	rb_thread_start_1();
+    }
     if (state) {
 	trace_func = 0;
@@ -1362,5 +1372,5 @@ ruby_exec()
 
     Init_stack((void*)&tmp);
-    PUSH_TAG(PROT_NONE);
+    PUSH_TAG(PROT_THREAD);
     PUSH_ITER(ITER_NOT);
     /* default visibility is private at toplevel */
@@ -1369,4 +1379,7 @@ ruby_exec()
 	eval_node(ruby_top_self, ruby_eval_tree);
     }
+    else if (state == TAG_THREAD) {
+	rb_thread_start_1();
+    }
     POP_ITER();
     POP_TAG();
@@ -6930,6 +6987,11 @@ proc_alloc(klass, proc)
     }
 
-    if (!proc && ruby_block->block_obj && CLASS_OF(ruby_block->block_obj) == klass) {
-	return ruby_block->block_obj;
+    if (!proc && ruby_block->block_obj) {
+	VALUE obj = ruby_block->block_obj;
+	if (CLASS_OF(obj) != klass) {
+	    obj = proc_clone(obj);
+	    RBASIC(obj)->klass = klass;
+	}
+	return obj;
     }
     block = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data);
@@ -7205,10 +7267,10 @@ proc_binding(proc)
 }
 
-static VALUE
-block_pass(self, node)
-    VALUE self;
-    NODE *node;
+VALUE
+rb_block_pass(func, arg, proc)
+    VALUE (*func) _((VALUE));
+    VALUE arg;
+    VALUE proc;
 {
-    VALUE proc = rb_eval(self, node->nd_body);	/* OK */
     VALUE b;
     struct BLOCK * volatile old_block;
@@ -7222,5 +7284,5 @@ block_pass(self, node)
     if (NIL_P(proc)) {
 	PUSH_ITER(ITER_NOT);
-	result = rb_eval(self, node->nd_iter);
+	result = (*func)(arg);
 	POP_ITER();
 	return result;
@@ -7243,5 +7305,5 @@ block_pass(self, node)
     if (ruby_block && ruby_block->block_obj == proc) {
 	PUSH_ITER(ITER_PRE);
-	result = rb_eval(self, node->nd_iter);
+	result = (*func)(arg);
 	POP_ITER();
 	return result;
@@ -7267,5 +7329,5 @@ block_pass(self, node)
 	if (safe > ruby_safe_level)
 	    ruby_safe_level = safe;
-	result = rb_eval(self, node->nd_iter);
+	result = (*func)(arg);
     }
     else if (state == TAG_BREAK && TAG_DST()) {
@@ -7296,4 +7358,28 @@ block_pass(self, node)
 }
 
+struct block_arg {
+    VALUE self;
+    NODE *iter;
+};
+
+static VALUE
+call_block(arg)
+    struct block_arg *arg;
+{
+    return rb_eval(arg->self, arg->iter);
+}
+
+static VALUE
+block_pass(self, node)
+    VALUE self;
+    NODE *node;
+{
+    struct block_arg arg;
+    arg.self = self;
+    arg.iter = node->nd_iter;
+    return rb_block_pass((VALUE (*)_((VALUE)))call_block,
+			 (VALUE)&arg, rb_eval(self, node->nd_body));
+}
+
 struct METHOD {
     VALUE klass, rklass;
@@ -9402,4 +9500,28 @@ rb_thread_stop_timer()
 #endif
 
+static struct {
+    rb_thread_t thread;
+    VALUE proc;
+    void *arg;
+} new_thread_param;
+
+NORETURN(static void rb_thread_terminated _((rb_thread_t, int, enum thread_status)));
+static VALUE rb_thread_yield _((VALUE, rb_thread_t));
+
+static void
+thread_inseart(th)
+    rb_thread_t th;
+{
+    if (!th->next) {
+	/* merge in thread list */
+	th->prev = curr_thread;
+	curr_thread->next->prev = th;
+	th->next = curr_thread->next;
+	curr_thread->next = th;
+	th->priority = curr_thread->priority;
+	th->thgroup = curr_thread->thgroup;
+    }
+}
+
 static VALUE
 rb_thread_start_0(fn, arg, th)
@@ -9411,4 +9533,5 @@ rb_thread_start_0(fn, arg, th)
     struct BLOCK *volatile saved_block = 0, *block;
     enum thread_status status;
+    struct tag *tt = 0;
     int state;
 
@@ -9431,7 +9554,19 @@ rb_thread_start_0(fn, arg, th)
 #endif
 
+    if (fn == rb_thread_yield) {
+	for (tt = prot_tag; tt; tt = tt->prev) {
+	    if (tt->tag == PROT_THREAD) {
+		new_thread_param.thread = th;
+		new_thread_param.proc = rb_block_proc();
+		new_thread_param.arg = arg;
+		break;
+	    }
+	}
+    }
+
     if (THREAD_SAVE_CONTEXT(curr_thread)) {
-	return th_save->thread;
+	return th->thread;
     }
+    if (tt) longjmp(tt->buf, TAG_THREAD);
 
     if (ruby_block) {		/* should nail down higher blocks */
@@ -9444,13 +9579,5 @@ rb_thread_start_0(fn, arg, th)
     scope_dup(ruby_scope);
 
-    if (!th->next) {
-	/* merge in thread list */
-	th->prev = curr_thread;
-	curr_thread->next->prev = th;
-	th->next = curr_thread->next;
-	curr_thread->next = th;
-	th->priority = curr_thread->priority;
-	th->thgroup = curr_thread->thgroup;
-    }
+    thread_inseart(th);
 
     PUSH_TAG(PROT_THREAD);
@@ -9480,4 +9608,14 @@ rb_thread_start_0(fn, arg, th)
     }
 
+    rb_thread_terminated(th, state, status);
+    return 0;			/* not reached */
+}
+
+static void
+rb_thread_terminated(th, state, status)
+    rb_thread_t th;
+    int state;
+    enum thread_status status;
+{
     if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
 	th->flags |= THREAD_RAISED;
@@ -9509,5 +9647,49 @@ rb_thread_start_0(fn, arg, th)
     rb_thread_schedule();
     ruby_stop(0);		/* last thread termination */
-    return 0;			/* not reached */
+}
+
+struct thread_yield_arg {
+    VALUE arg;
+    rb_thread_t thread;
+};
+
+static VALUE
+rb_thread_yield_0(arg)
+    struct thread_yield_arg *arg;
+{
+    return rb_thread_yield(arg->arg, arg->thread);
+}
+
+static void
+rb_thread_start_1()
+{
+    rb_thread_t th = new_thread_param.thread;
+    VALUE proc = new_thread_param.proc;
+    struct thread_yield_arg arg;
+    enum thread_status status;
+    int state;
+
+    arg.arg = (VALUE)new_thread_param.arg;
+    arg.thread = th;
+
+    thread_inseart(th);
+
+    PUSH_TAG(PROT_NONE);
+    if ((state = EXEC_TAG()) == 0) {
+	if (THREAD_SAVE_CONTEXT(th) == 0) {
+	    curr_thread = th;
+	    th->result = rb_block_pass(rb_thread_yield_0, (VALUE)&arg, proc);
+	}
+    }
+    else if (TAG_DST()) {
+	th->result = prot_tag->retval;
+    }
+    th = arg.thread;
+    POP_TAG();
+    status = th->status;
+
+    if (th == main_thread) ruby_stop(state);
+    rb_thread_remove(th);
+    rb_thread_terminated(th, state, status);
 }
 
@@ -10240,4 +11083,5 @@ rb_f_throw(argc, argv)
 	}
 	if (tt->tag == PROT_THREAD) {
+	    if (curr_thread == main_thread) goto uncaught;
 	    rb_raise(rb_eThreadError, "uncaught throw `%s' in thread 0x%lx",
 		     rb_id2name(SYM2ID(tag)),
@@ -10247,4 +11091,5 @@ rb_f_throw(argc, argv)
     }
     if (!tt) {
+      uncaught:
 	rb_name_error(SYM2ID(tag), "uncaught throw `%s'", rb_id2name(SYM2ID(tag)));
     }
Index: ruby.h
===================================================================
RCS file: /cvs/ruby/src/ruby/ruby.h,v
retrieving revision 1.89
diff -u -2 -p -r1.89 ruby.h
--- ruby.h	22 Aug 2003 08:09:57 -0000	1.89
+++ ruby.h	12 Sep 2003 08:29:31 -0000
@@ -541,4 +541,5 @@ VALUE rb_yield_splat _((VALUE));
 int rb_block_given_p _((void));
 VALUE rb_iterate _((VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE));
+VALUE rb_block_pass _((VALUE(*)(VALUE),VALUE,VALUE));
 VALUE rb_rescue _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));
 VALUE rb_rescue2 __((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE,...));


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread

Prev Next