[#11680] fork_and_kill_other_threads — "NAKAMURA, Hiroshi" <nakahiro@...>
なひです。[ruby-list:26165]からもって来ました。
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
On Sun, 3 Dec 2000 23:33:41 +0900
まつもと ゆきひろです
なひです。
まつもと ゆきひろです
なひです。
まつもと ゆきひろです
なひです。
まつもと ゆきひろです
なひです。
[#11688] [bug?] cgi.rb / rb_exec_end_proc — Takaaki Tateishi <ttate@...>
立石です.
[#11697] ruby_run() — "K.Kosako" <kosako@...>
細かい話で恐縮ですが、プログラムを読んでいて
[#11733] Ruby I18N 改め M17N — とみたまさひろ <tommy@...>
とみたです。
まつもと ゆきひろです
とみたです。
まつもと ゆきひろです
> |もし MBString を Ruby の基本クラスとして実装するんでしたら、
まつもと ゆきひろです
> |struct RString(とstruct RMBString)からorigメンバを削っても、
[#11758] [PATCH & Q] literal in condition — "Nobuyoshi.Nakada" <nobu.nakada@...>
なかだです。
[#11777] Maybe IRB bug!! — Kazuhiro NISHIYAMA <zn@...>
irbで$SAFE=4にしたらSecurityErrorで終了してしまいました。
けいじゅ@日本ラショナルソフトウェアです.
[#11789] mswin32 [Q & patch] mkmf.rb — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
なかだです。
まつもと ゆきひろです
なかだです。
こんにちは、なかむら(う)です。
なかだです。
[#11818] Hash#inspect with symbol key — Hiroshi IGARASHI <igarashi@...>
いがらしです。ご無沙汰してます。
[#11820] pack/unpack の '_' — Koji Arai <JCA02266@...>
新井です。
[#11835] fork exception — nobu.nakada@...
なかだです。
[#11848] Where'd all the Ruby's history gone? — "Akinori MUSHA" <knu@...>
さっき気付いたんですが、 Ruby のレポジトリから過去分がごっそり
まつもと ゆきひろです
On Tue, 26 Dec 2000 14:58:07 +0900
まつもと ゆきひろです
At Tue, 26 Dec 2000 17:44:57 +0900,
On Tue, 26 Dec 2000 21:24:19 +0900
At Fri, 29 Dec 2000 18:56:03 +0900,
On Fri, 29 Dec 2000 19:07:12 +0900
At Fri, 29 Dec 2000 19:35:56 +0900,
On Fri, 29 Dec 2000 19:55:59 +0900
At Sat, 6 Jan 2001 20:33:58 +0900,
えぐち@エスアンドイー です。
[#11849] rb_io_flush — Kazuhiro Yoshida <moriq.kazuhiro@...>
もりきゅうです。
[#11852] local variable extent problem? — Tanaka Akira <akr@...17n.org>
どうも、Ruby のバグのような気がするものを見つけたのですが、もしかした
まつもと ゆきひろです
In article <977817486.100168.31162.nullmailer@ev.netlab.zetabits.com>,
まつもと ゆきひろです
In article <977819010.870991.31953.nullmailer@ev.netlab.zetabits.com>,
まつもと ゆきひろです
At Tue, 26 Dec 2000 17:50:11 +0900,
まつもと ゆきひろです
こんばんは。もうこんな時間だ。。
まつもと ゆきひろです
[#11885] New CVSweb — "Akinori MUSHA" <knu@...>
以下の URL に新しい CVSweb を置きました。新しいレポジトリを
[#11898] `www' module is available again — "Akinori MUSHA" <knu@...>
www レポジトリをマージしました。今のところ、 ruby と www の
[ruby-dev:11835] fork exception
なかだです。
忘れたころに、というか 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はできる。
中田 伸悦