[#11680] fork_and_kill_other_threads — "NAKAMURA, Hiroshi" <nakahiro@...>

なひです。[ruby-list:26165]からもって来ました。

27 messages 2000/12/02
[#11681] Re: fork_and_kill_other_threads — Masatoshi SEKI <m_seki@...> 2000/12/02

[#11682] Re: fork_and_kill_other_threads — matz@... (Yukihiro Matsumoto) 2000/12/02

まつもと ゆきひろです

[#11685] Re: fork_and_kill_other_threads — nobu.nakada@... 2000/12/03

なかだです。

[#11687] Re: fork_and_kill_other_threads — matz@... (Yukihiro Matsumoto) 2000/12/03

まつもと ゆきひろです

[#11708] Re: fork_and_kill_other_threads — Kazuhiro NISHIYAMA <zn@...> 2000/12/06

On Sun, 3 Dec 2000 23:33:41 +0900

[#11709] Re: fork_and_kill_other_threads — matz@... (Yukihiro Matsumoto) 2000/12/06

まつもと ゆきひろです

[#11710] Re: fork_and_kill_other_threads — "NAKAMURA, Hiroshi" <nakahiro@...> 2000/12/06

なひです。

[#11713] Re: fork_and_kill_other_threads — matz@... (Yukihiro Matsumoto) 2000/12/06

まつもと ゆきひろです

[#11716] Re: fork_and_kill_other_threads — "NAKAMURA, Hiroshi" <nakahiro@...> 2000/12/06

なひです。

[#11718] Re: fork_and_kill_other_threads — matz@... (Yukihiro Matsumoto) 2000/12/06

まつもと ゆきひろです

[#11722] Re: fork_and_kill_other_threads — "NAKAMURA, Hiroshi" <nakahiro@...> 2000/12/07

なひです。

[#11733] Ruby I18N 改め M17N — とみたまさひろ <tommy@...>

とみたです。

17 messages 2000/12/07
[#11735] Re: Ruby I18N 改め M17N — matz@... (Yukihiro Matsumoto) 2000/12/08

まつもと ゆきひろです

[#11751] Re: Ruby I18N 改め M17N — とみたまさひろ <tommy@...> 2000/12/13

とみたです。

[#11752] Re: Ruby I18N 改め M17N — matz@... (Yukihiro Matsumoto) 2000/12/13

まつもと ゆきひろです

[#11789] mswin32 [Q & patch] mkmf.rb — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

14 messages 2000/12/18
[#11790] Re: mswin32 [Q & patch] mkmf.rb — "Nobuyoshi.Nakada" <nobu.nakada@...> 2000/12/19

なかだです。

[#11848] Where'd all the Ruby's history gone? — "Akinori MUSHA" <knu@...>

 さっき気付いたんですが、 Ruby のレポジトリから過去分がごっそり

27 messages 2000/12/25
[#11853] Re: Where'd all the Ruby's history gone? — matz@... (Yukihiro Matsumoto) 2000/12/26

まつもと ゆきひろです

[#11861] Re: Where'd all the Ruby's history gone? — Kazuhiro NISHIYAMA <zn@...> 2000/12/26

On Tue, 26 Dec 2000 14:58:07 +0900

[#11862] Re: Where'd all the Ruby's history gone? — matz@... (Yukihiro Matsumoto) 2000/12/26

まつもと ゆきひろです

[#11869] Re: Where'd all the Ruby's history gone? — "Akinori MUSHA" <knu@...> 2000/12/26

At Tue, 26 Dec 2000 17:44:57 +0900,

[#11894] Re: Where'd all the Ruby's history gone? — Kazuhiro NISHIYAMA <zn@...> 2000/12/29

On Tue, 26 Dec 2000 21:24:19 +0900

[#11895] Re: Where'd all the Ruby's history gone? — "Akinori MUSHA" <knu@...> 2000/12/29

At Fri, 29 Dec 2000 18:56:03 +0900,

[#11896] Re: Where'd all the Ruby's history gone? — Kazuhiro NISHIYAMA <zn@...> 2000/12/29

On Fri, 29 Dec 2000 19:07:12 +0900

[#11852] local variable extent problem? — Tanaka Akira <akr@...17n.org>

どうも、Ruby のバグのような気がするものを見つけたのですが、もしかした

21 messages 2000/12/26
[#11855] Re: local variable extent problem? — matz@... (Yukihiro Matsumoto) 2000/12/26

まつもと ゆきひろです

[#11857] Re: local variable extent problem? — Tanaka Akira <akr@...17n.org> 2000/12/26

In article <977817486.100168.31162.nullmailer@ev.netlab.zetabits.com>,

[#11859] Re: local variable extent problem? — matz@... (Yukihiro Matsumoto) 2000/12/26

まつもと ゆきひろです

[#11860] Re: local variable extent problem? — Tanaka Akira <akr@...17n.org> 2000/12/26

In article <977819010.870991.31953.nullmailer@ev.netlab.zetabits.com>,

[#11863] Re: local variable extent problem? — matz@... (Yukihiro Matsumoto) 2000/12/26

まつもと ゆきひろです

[#11865] Re: local variable extent problem? — "Akinori MUSHA" <knu@...> 2000/12/26

At Tue, 26 Dec 2000 17:50:11 +0900,

[#11874] Re: local variable extent problem? — matz@... (Yukihiro Matsumoto) 2000/12/26

まつもと ゆきひろです

[ruby-dev:11835] fork exception

From: nobu.nakada@...
Date: 2000-12-24 22:41:04 UTC
List: ruby-dev #11835
なかだです。

  忘れたころに、というか 1.7 ネタというか、なんとなく今の
rb_thread_atfork() はヤバすぎるっつうか、finalizer を考えたらほ
とんど意味がないような気がするので、修正案です。

  fork() 前に呼ばれる Thread#prefork みたいのもあった方がいいか
も知んない…。

--- Thread#atfork do ... end
    fork() した後で fork() したスレッド以外のスレッドで評価され
    る

--- Thread#atfork=(atfork)
    atfork によって fork() 後の動作を決める
    : Proc
      atfork を呼び出す
    : true
      そのまま継続
    : false
    : nil
      ForkedException を上げる(デフォルト)

  オブジェクトごとに決めさせるって方法は、実装が難しいというか
めんどくさそうで、残念ながらうまい手が思いつきませんでした。


Index: error.c
===================================================================
RCS file: /home/cvs/ruby/error.c,v
retrieving revision 1.19
diff -u -2 -p -r1.19 error.c
--- error.c	2000/11/14 07:10:20	1.19
+++ error.c	2000/12/24 15:04:49
@@ -268,4 +268,5 @@ VALUE rb_eNameError;
 VALUE rb_eSyntaxError;
 VALUE rb_eLoadError;
+VALUE rb_eForkedException;
 
 VALUE rb_eSystemCallError;
@@ -558,4 +559,5 @@ Init_Exception()
     rb_eInterrupt   = rb_define_class("Interrupt", rb_eException);
     rb_eSignal      = rb_define_class("SignalException", rb_eException);
+    rb_eForkedException = rb_define_class("ForkedException", rb_eException);
 
     rb_eStandardError = rb_define_class("StandardError", rb_eException);
Index: eval.c
===================================================================
RCS file: /home/cvs/ruby/eval.c,v
retrieving revision 1.136
diff -u -2 -p -r1.136 eval.c
--- eval.c	2000/12/22 03:21:54	1.136
+++ eval.c	2000/12/24 15:30:14
@@ -6757,4 +6757,6 @@ struct thread {
 
     VALUE thread;
+
+    VALUE atfork;
 };
 
@@ -6873,4 +6875,5 @@ static VALUE th_raise_argv[2];
 static char *th_raise_file;
 static int   th_raise_line;
+static void(*th_defer_func) _((VALUE));
 static VALUE th_cmd;
 static int   th_sig;
@@ -6883,4 +6886,5 @@ static char *th_signm;
 #define RESTORE_RAISE		5
 #define RESTORE_SIGNAL		6
+#define RESTORE_DEFER		7
 
 static void
@@ -6923,4 +6927,6 @@ rb_thread_save_context(th)
 }
 
+static void rb_thread_restore_context _((rb_thread_t,int));
+
 static int
 thread_switch(n)
@@ -6949,4 +6955,21 @@ thread_switch(n)
 	rb_raise(rb_eSignal, "SIG%s", th_signm);
 	break;
+      case RESTORE_DEFER:
+	{
+	    char *file = th_raise_file;
+	    int line = th_raise_line;
+	    void (*proc)_((VALUE)) = th_defer_func;
+	    VALUE arg = *th_raise_argv;
+
+	    rb_thread_save_context(curr_thread);
+	    if (!setjmp(curr_thread->context)) {
+		rb_thread_restore_context(main_thread, RESTORE_NORMAL);
+	    }
+	    ruby_frame->last_func = 0;
+	    ruby_sourcefile = file;
+	    ruby_sourceline = line;
+	    proc(arg);
+	}
+	break;
       case RESTORE_NORMAL:
       default:
@@ -6959,6 +6982,4 @@ thread_switch(n)
     (rb_thread_save_context(th),thread_switch(setjmp((th)->context)))
 
-static void rb_thread_restore_context _((rb_thread_t,int));
-
 static void
 stack_extend(th, exit)
@@ -7809,4 +7830,5 @@ rb_thread_abort_exc_set(thread, val)
     th->gid = 1;\
     th->locals = 0;\
+    th->atfork = Qnil;\
 } while(0)
 
@@ -8330,4 +8352,47 @@ rb_thread_inspect(thread)
 }
 
+static VALUE
+thread_atfork(thread)
+    VALUE thread;
+{
+    rb_thread_t th = rb_thread_check(thread);
+    if (rb_block_given_p()) {
+	th->atfork = rb_f_lambda();
+	return thread;
+    }
+    return th->atfork;
+}
+
+static VALUE
+thread_set_atfork(thread, atfork)
+    VALUE thread, atfork;
+{
+    rb_thread_t th = rb_thread_check(thread);
+    switch (atfork) {
+      case Qtrue:
+      case Qfalse:
+      case Qnil:
+	break;
+      default:
+	if (!rb_obj_is_proc(atfork)) {
+	    rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc)",
+		     rb_class2name(CLASS_OF(atfork)));
+	}
+    }
+    return th->atfork = atfork;
+}
+
+static void
+atfork_proc(arg)
+    VALUE arg;
+{
+    if (RTEST(atfork)) {
+	proc_call(arg, Qundef);
+    }
+    else {
+	rb_f_raise(1, &rb_eForkedException);
+    }
+}
+
 void
 rb_thread_atfork()
@@ -8336,13 +8401,24 @@ rb_thread_atfork()
 
     if (rb_thread_alone()) return;
-    FOREACH_THREAD(th) {
-	if (th != curr_thread) {
-	    th->status = THREAD_KILLED;
+    main_thread = curr_thread;
+    th_raise_file = ruby_sourcefile;
+    th_raise_line = ruby_sourceline;
+    th_defer_func = atfork_proc;
+    FOREACH_THREAD_FROM(main_thread, th) {
+	if (th == main_thread) continue;
+	if (th->atfork == Qtrue) continue;
+	switch (th->status) {
+	  case THREAD_RUNNABLE:
+	  case THREAD_STOPPED:
+	    rb_thread_ready(th);
+	    curr_thread = th;
+	    if (THREAD_SAVE_CONTEXT(main_thread)) break;
+	    th_raise_argv[0] = th->atfork;
+	    rb_thread_restore_context(th, RESTORE_DEFER);
 	}
     }
-    END_FOREACH(th);
-    main_thread = curr_thread;
-    curr_thread->next = curr_thread;
-    curr_thread->prev = curr_thread;
+    END_FOREACH_FROM(main_thread, th);
+    curr_thread = main_thread;
+    rb_thread_schedule();
 }
 
@@ -8514,4 +8590,7 @@ Init_Thread()
 
     rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);
+
+    rb_define_method(rb_cThread, "atfork", thread_atfork, 0);
+    rb_define_method(rb_cThread, "atfork=", thread_set_atfork, 1);
 
     /* allocate main thread */
Index: ruby.h
===================================================================
RCS file: /home/cvs/ruby/ruby.h,v
retrieving revision 1.29
diff -u -2 -p -r1.29 ruby.h
--- ruby.h	2000/11/27 09:23:26	1.29
+++ ruby.h	2000/12/24 15:05:14
@@ -541,4 +541,5 @@ EXTERN VALUE rb_eNameError;
 EXTERN VALUE rb_eSyntaxError;
 EXTERN VALUE rb_eLoadError;
+EXTERN VALUE rb_eForkedException;
 
 #if defined(__GNUC__) && __GNUC__ >= 2 && !defined(RUBY_NO_INLINE)


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

In This Thread

Prev Next