[#7300] resolver を呼ばない UDPsocket#recvfrom — Toshihiko SHIMOKAWA / 下川俊彦 <toshi@...>

あんまり ruby-dev な話でも無いのですが、ちょっとした機能拡張の提案なので、

12 messages 1999/07/12
[#7321] Re: resolver を呼ばない UDPsocket#recvfrom — Toshihiko SHIMOKAWA / 下川俊彦 <toshi@...> 1999/07/15

From: Toshihiko SHIMOKAWA / 下川俊彦 <toshi@csce.kyushu-u.ac.jp>

[#7313] Ruby 1.3.5 — Yukihiro Matsumoto <matz@...>

Ruby 1.3.5 is out, check out:

59 messages 1999/07/15
[#7318] Re: Ruby 1.3.5 — WATANABE Hirofumi <watanabe@...> 1999/07/15

わたなべです.

[#7326] Re: Ruby 1.3.5 — Wakou Aoyama <wakou@...> 1999/07/15

青山です。

[#7331] Re: Ruby 1.3.5 — matz@... (Yukihiro Matsumoto) 1999/07/16

まつもと ゆきひろです

[#7340] Re: Ruby 1.3.5 — Wakou Aoyama <wakou@...> 1999/07/16

青山です。

[#7368] Re: Ruby 1.3.5 — matz@... (Yukihiro Matsumoto) 1999/07/19

まつもと ゆきひろです

[#7373] Re: Ruby 1.3.5 — Shin-ichiro Hara <sinara@...> 1999/07/19

原です。

[#7374] Re: Ruby 1.3.5 — matz@... (Yukihiro Matsumoto) 1999/07/19

まつもと ゆきひろです

[#7382] Re: Ruby 1.3.5 — Wakou Aoyama <wakou@...> 1999/07/19

青山です。

[#7386] Re: Ruby 1.3.5 — matz@... (Yukihiro Matsumoto) 1999/07/21

まつもと ゆきひろです

[#7388] Re: Ruby 1.3.5 — Wakou Aoyama <wakou@...> 1999/07/21

青山です。

[#7387] [PATCH]extconf.rb, tcltklib.c, and rubytest.rb for NetBSD — Ryo HAYASAKA <hayasaka@...21.u-aizu.ac.jp>

早坂@会津大学です。

10 messages 1999/07/21

[#7466] [PATCH] for djgpp — WATANABE Hirofumi <watanabe@...>

わたなべです.

21 messages 1999/07/29
[#7467] Re: [PATCH] for djgpp — Katsuyuki Komatsu <komatsu@...> 1999/07/29

小松です。

[ruby-dev:7515] Re: ERb について

From: matz@... (Yukihiro Matsumoto)
Date: 1999-07-31 16:41:45 UTC
List: ruby-dev #7515
まつもと ゆきひろです

[ruby-list:15799]の話題ですが、難しいので引越し。

In message "[ruby-list:15799] Re: ERb について"
    on 99/08/01, matsuo hisanori <matsuo_hisanori@pop21.odn.ne.jp> writes:

|更にせきさんの検討によると、1.3でも変なことが起こるようです。
|例えば以下のスクリプトを僕の環境
|
|ruby 1.3.6 (1999-07-28) [i386-cygwin]
|
|で動かしてみると。
|
|(1..1000).each{|i|
|  begin
|    begin
|      raise 'out of eRuby'
|    rescue
|      Thread.start { true }.value
|    end
|  rescue
|    p "#{i}回目の例外が再発生? #{$!}"
|  end
|}

えーと、この問題は以下の二つの問題の組合せでした。

  * rescue節でスタートされたThreadではその中では例外が発生し
    ていないのに $! がセットされている

  * joinは例外の再発生をするはずなのに、すでに終了したスレッ
    ドに対しては例外チェックをしていなかった

で、Thread#valueの中で間接的に呼ばれているThread#joinが $! 
がセットされていると例外を再発生する挙動になっていましたが、
前者の問題のためにスレッド内部で例外が発生してなくても、再発
生させていたのでした。

ところが、後者のためにこの例ではほとんどのタイミングでjoinす
るまえにスレッドの実行は終了しているので、例外再発生のコード
に到達してなかったのでした。で、タイミングによって例外が発生
したりしなかったりすると。

後者は単なるチェック条件の変更だけなので、簡単に修正するとちゃ
んと(?)毎回例外を再発生するようになります。で、スレッドにフ
ラグを持たせて、自分の中で例外が発生したかどうかを記録するよ
うにして、前者の問題も解決させました。

で、パッチです。[ruby-dev:7504]の対策も含んでます。

--- /tmp/eval.c	Sun Aug  1 01:34:35 1999
+++ eval.c	Sun Aug  1 01:23:30 1999
@@ -422,3 +422,3 @@
     int vmode;
-    int d_scope;
+    int flags;
     struct RVarmap *d_vars;
@@ -427,2 +427,6 @@
 };
+
+#define BLOCK_D_SCOPE 1
+#define BLOCK_DYNAMIC 2
+
 static struct BLOCK *ruby_block;
@@ -443,3 +447,3 @@
     _block.vmode = scope_vmode;		\
-    _block.d_scope = Qtrue;		\
+    _block.flags = BLOCK_D_SCOPE;	\
     _block.d_vars = ruby_dyna_vars;	\
@@ -1161,3 +1165,3 @@
 	*state = status;
-	if (status == 0) {
+	if (status) {
 	    JUMP_TAG(status);
@@ -1933,3 +1937,3 @@
 
-		    _block.d_scope = Qfalse;
+		    _block.flags &= ~BLOCK_D_SCOPE;
 		    recv = rb_eval(self, node->nd_iter);
@@ -3140,3 +3144,3 @@
     ruby_block = block->prev;
-    if (block->d_scope) {
+    if (block->flags & BLOCK_D_SCOPE) {
 	/* put place holder for dynamic (in-block) local variables */
@@ -4298,2 +4302,3 @@
 
+/* function to call func under the specified class/module context */
 static VALUE
@@ -4339,2 +4344,3 @@
 
+/* string eval under the class/module context */
 static VALUE
@@ -4359,2 +4365,27 @@
 {
+    if (ruby_block->flags & BLOCK_DYNAMIC) {
+	struct BLOCK * volatile old_block = ruby_block;
+	struct BLOCK block = *ruby_block;
+	volatile VALUE cbase = ruby_block->frame.cbase;
+	/* cbase should be pointed from volatile local variable */
+	/* to be protected from GC. 				*/
+	VALUE result;
+	int state;
+
+	/* copy the block to avoid modifying global data. */
+	block.frame.cbase = ruby_frame->cbase;
+	ruby_block = &block;
+
+	PUSH_TAG(PROT_NONE);
+	if ((state = EXEC_TAG()) == 0) {
+	    result = rb_yield_0(self, self, ruby_class);
+	}
+	POP_TAG();
+	ruby_block = old_block;
+	if (state) JUMP_TAG(state);
+	
+	return result;
+    }
+    /* static block, no need to restore */
+    ruby_block->frame.cbase = ruby_frame->cbase;
     return rb_yield_0(self, self, ruby_class);
@@ -4362,2 +4393,3 @@
 
+/* block eval under the class/module context */
 static VALUE
@@ -5416,2 +5448,3 @@
     }
+    data->flags |= BLOCK_DYNAMIC;
 
@@ -5873,3 +5906,3 @@
     VALUE trace;
-    int misc;			/* misc. states (vmode/rb_trap_immediate) */
+    int flags;		/* misc. states (vmode/rb_trap_immediate/raised) */
 
@@ -5898,2 +5931,4 @@
 
+#define THREAD_RAISED 0x200
+
 static thread_t curr_thread = 0;
@@ -6027,3 +6062,3 @@
     th->block = ruby_block;
-    th->misc = scope_vmode | (rb_trap_immediate<<8);
+    th->flags = scope_vmode | (rb_trap_immediate<<8);
     th->iter = ruby_iter;
@@ -6095,4 +6130,4 @@
     ruby_block = th->block;
-    scope_vmode = th->misc&SCOPE_MASK;
-    rb_trap_immediate = th->misc>>8;
+    scope_vmode = th->flags&SCOPE_MASK;
+    rb_trap_immediate = (th->flags&0x100)?1:0;
     ruby_iter = th->iter;
@@ -6565,14 +6600,15 @@
 
-    if (rb_thread_dead(th)) return thread;
-    if (th == curr_thread)
-	rb_raise(rb_eThreadError, "recursive join");
-    if ((th->wait_for & WAIT_JOIN) && th->join == curr_thread)
-	rb_raise(rb_eThreadError, "Thread#join: deadlock");
-    curr_thread->status = THREAD_STOPPED;
-    curr_thread->join = th;
-    num_waiting_on_join++;
-    curr_thread->wait_for |= WAIT_JOIN;
-    rb_thread_schedule();
+    if (!rb_thread_dead(th)) {
+	if (th == curr_thread)
+	    rb_raise(rb_eThreadError, "recursive join");
+	if ((th->wait_for & WAIT_JOIN) && th->join == curr_thread)
+	    rb_raise(rb_eThreadError, "Thread#join: deadlock - mutual join");
+	curr_thread->status = THREAD_STOPPED;
+	curr_thread->join = th;
+	num_waiting_on_join++;
+	curr_thread->wait_for |= WAIT_JOIN;
+	rb_thread_schedule();
+    }
 
-    if (!NIL_P(th->errinfo)) {
+    if (!NIL_P(th->errinfo) && (th->flags & THREAD_RAISED)) {
 	VALUE oldbt = get_backtrace(th->errinfo);
@@ -6897,2 +6933,3 @@
     if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
+	th->flags |= THREAD_RAISED;
 	if (state == TAG_FATAL) { 
@@ -6906,3 +6943,3 @@
 	}
-	else if (thread_abort || curr_thread->abort || RTEST(ruby_debug)) {
+	else if (thread_abort || th->abort || RTEST(ruby_debug)) {
 	    VALUE err = rb_exc_new(rb_eSystemExit, 0, 0);
@@ -6913,3 +6950,3 @@
 	else {
-	    curr_thread->errinfo = ruby_errinfo;
+	    th->errinfo = ruby_errinfo;
 	}
@@ -6971,3 +7008,4 @@
     if (rb_thread_dead(th)) {
-	if (NIL_P(th->errinfo)) return Qfalse;
+	if (NIL_P(th->errinfo) && (th->flags & THREAD_RAISED))
+	    return Qfalse;
 	return Qnil;

In This Thread

Prev Next