[#11110] README.EXT.jp — Kazuhiro NISHIYAMA <zn@...>
README.EXT.jpを見てて気になったところがあったのでパッチです。
[#11115] proc{|a|}.arity — Kazuhiro NISHIYAMA <zn@...>
proc{|a|}.arity #=> -2
[#11131] Re: SIGINT on windows — Daisuke Aoki <dai@...>
青木です。
青木です。
青木です。
なかだです。
なかだです。
青木です。
なかだです。
[#11138] copy-on-write for substr — Shugo Maeda <shugo@...>
前田です。
前田です。
まつもと ゆきひろです
[#11146] /(?=a)b/ — Minero Aoki <aamine@...>
あおきです。
[#11158] [Patch] tracer.rb in 1.6.1 — "NAKAMURA, Hiroshi" <nakahiro@...>
なひです.
[#11159] net/protocol.rb ProtocolError#initialize — matz@... (Yukihiro Matsumoto)
まつもと ゆきひろです
[#11161] 複数 Thread で止まった — Kazuhiro NISHIYAMA <zn@...>
あるプログラムで//pのwarningが別スレッドの$!.to_sと
[#11166] cgi.rb — akira yamada / やまだあきら <akira@...>
[#11183] EPOC32 and Ruby 1.7 — WATANABE Hirofumi <eban@...>
わたなべです.
まつもと ゆきひろです
On Fri, 13 Oct 2000 00:17:14 +0900
同じ問題を短いスクリプトで再現できました。
まつもと ゆきひろです
On Sat, 14 Oct 2000 03:41:18 +0900
On Sat, 14 Oct 2000 05:17:32 +0900
まつもと ゆきひろです
On Sat, 14 Oct 2000 23:45:08 +0900
まつもと ゆきひろです
前田です。
[ruby-dev:11205]と同じスクリプトで-dをつけていると
On Sun, 15 Oct 2000 02:11:02 +0900
On Sun, 15 Oct 2000 04:24:58 +0900
[#11196] malloc trouble in thread — GOTOU YUUZOU <gotoyuzo@...>
ごとうゆうぞうです。
[#11306] Ruby I18N — matz@... (Yukihiro Matsumoto)
まつもと ゆきひろです
たけ(tk)です。
長沢です。
まつもと ゆきひろです
前田です。
高橋征義です。
At Mon, 30 Oct 2000 13:15:23 +0900,
某2ちゃんねるで自分の名前を見つけてびびった高橋征義です。
まつもと ゆきひろです
たけ(tk)です。
高橋征義です。
まつもと ゆきひろです
高橋征義です。
たけ(tk)です。
まつもと ゆきひろです
たけ(tk)です。
まつもと ゆきひろです
永井@知能.九工大です.
まつもと ゆきひろです
たけ(tk)です。 ・・ 長文ご注意。
まつもと ゆきひろです
At Tue, 7 Nov 2000 15:46:29 +0900,
まつもと ゆきひろです
In article <E13t3dt-0002Fp-00@ev.netlab.zetabits.co.jp>,
まつもと ゆきひろです
たけ(tk)です。
At Tue, 7 Nov 2000 19:06:27 +0900,
たけ(tk)です。
あおきです。
たけ(tk)です。
あおきです。
On Wed, 8 Nov 2000 15:41:58 +0900
あおきです。
On Fri, 10 Nov 2000 01:59:09 +0900
In article <E13t4Hq-0002GS-00@ev.netlab.zetabits.co.jp>,
まつもと ゆきひろです
In article <E13tMYW-0002te-00@ev.netlab.zetabits.co.jp>,
まつもと ゆきひろです
たけ(tk)です。
まつもと ゆきひろです
たけ(tk)です。
たけ(tk)です。
まつもと ゆきひろです
たけ(tk)です。
まつもと ゆきひろです
たけ(tk)です。
まつもと ゆきひろです
In article <E13tNkT-00030l-00@ev.netlab.zetabits.co.jp>,
たけ(tk)です。
たけ(tk)です。
[#11312] confused error message on Windows 2000 — Katsuyuki Komatsu <komatsu@...>
小松です。
まつもと ゆきひろです
なかだです。
[ruby-dev:11119] Re: SIGINT on windows
青木です。
うちの環境は、PC-98、Windows 95、Visual C++ 6.0+SP5 です。
NT とか 2000 とか 98 では試していません。
nobu.nakada@nifty.ne.jp wrote:
> となると、やっぱり signal thread で完了を待ってコンテキストを
> 戻してやらないとダメですか? でも SuspendThred() されるまでどう
> やって待とう。
安直な方法だと、
SuspendThread(hThread); result = ResumeThread(hThread);
とやって、result が 2 以上であればサスペンドしているとわかります
ので、あとはループで検知すれば・・・
> > もちろん、sighandle() は呼ばれてます。
> win32_main_context() に DebugBreak() を仕込んでみても引っかか
> らなかったんですが。
うちでは、printf() 使ってデバッグしてますが、それでちゃんと
sighandle() 2回呼ばれていることを確認してます。
> 一応目は通したものの、かなり大がかりな感じなので…。あれを持っ
> て来るなら素直に cygwin 版使えばいいじゃん、とか思ったりして。
ですね。
> > このあたりどう解決されるのか興味があります(^^;;
> どう解決できるのか私も知りたいです(;_;)
ほんと興味の尽きないところなのですが(;-;)
以下、Windows 95 上での 1.6.1 の動作での詳細。
1)ReadFile() で待機。
2)Ctrl-C で sighandle() が呼ばれる。
3)win32_main_context() が呼ばれる。
4)win32_main_context() の SuspendThread() でメインスレッドが
止まる。
5)win32_main_context() の SetThreadContext()でメインスレッドが
動き出す。4) の SuspendThread() が無効になっている。カーネル
モードにでもなっているのでは。ちなみに、SetThreadContext()
した以降 SuspendThread() するコード加えても、エラーにはならないが
止まらないので、ユーザーモードでないことしか考えられない。
6)win32_main_context() の ResumeThread() 以前にメインスレッドは
動いてる。多分、ResumeThread()しておかないと、ユーザーモードに
戻ったとき止まってしまうと思うが、このケースでは ResumuThread()
が意味なくなっている。
7)win32_call_handler() が呼ばれる。
7)win32_call_handler() の handler() が呼ばれる。
8)win32_call_handler() の SetThreadContext() を呼んだ直後から、
OS 全体の画面更新がストップする。キー操作は受け付けているので、
ENTER キーや Ctrl-Z とかで ReadFile() から抜けることは可能。
Ruby のプロセスが終わらない限り、画面更新のストップは続く。
ちなみに、もう一回、Ctrl-C したりすると完全に止まる。
Ctrl-Alt-Del で復旧は可能。
1) の ReadFile() での待機状態じゃない場合は、OS 全体の画面更新が
ストップすることはないようですが、2回目の Ctrl-C で固まったり
します。
win32_call_handler() ではなくて、win32_main_context() で
SetThreadContext() をしてみた場合は、ReadFile() 待機中でも
なんとか大丈夫にできましたが、ReadFile() 待機中じゃない場合の
Ctrl-C で、タイミング的に例外とか出たりしました。たぶん、私の
ミスが原因と思いますが不明です(^^: 以下、それに使った実験用
パッチ(1.6.1 からの差分)です。SuspendThread()で止めてないのは
上記の理由によります。
*** win32.c0 Wed Sep 27 07:36:34 2000
--- win32.c Mon Oct 02 15:00:00 2000
***************
*** 2565,2575 ****
SuspendThread(GetCurrentThread());
}
static void win32_call_handler(int arg, void (*handler)(int), CONTEXT
ctx)
{
handler(arg);
! ctx.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
! SetThreadContext(rb_MainThreadHandle, &ctx);
}
static int catch_interrupt(unsigned long msec)
--- 2565,2584 ----
SuspendThread(GetCurrentThread());
}
+ static volatile HANDLE hEvent_win32_call_hander1 = NULL;
+ static volatile HANDLE hEvent_win32_call_hander2 = NULL;
+ #if 0
static void win32_call_handler(int arg, void (*handler)(int), CONTEXT
ctx)
+ #else
+ static void win32_call_handler(int arg, void (*handler)(int))
+ #endif
{
handler(arg);
! ResetEvent(hEvent_win32_call_hander2);
! SetEvent(hEvent_win32_call_hander1);
! WaitForSingleObject(hEvent_win32_call_hander2,INFINITE);
! // ctx.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
! // SetThreadContext(rb_MainThreadHandle, &ctx);
}
static int catch_interrupt(unsigned long msec)
***************
*** 2586,2597 ****
--- 2595,2615 ----
int win32_main_context(int arg, void (*handler)(int))
{
+ CONTEXT ctx_orig;
+
if (!win32_thread_exclusive()) return FALSE;
+ #if 0
if (!catch_interrupt(0)) {
SetEvent(rb_InterruptEvent);
return FALSE;
}
+ #endif
+
+ if(hEvent_win32_call_hander1==NULL)
+ hEvent_win32_call_hander1 = CreateEvent(NULL,FALSE,FALSE,NULL);
+ if(hEvent_win32_call_hander2==NULL)
+ hEvent_win32_call_hander2 = CreateEvent(NULL,FALSE,FALSE,NULL);
{
CONTEXT ctx;
***************
*** 2599,2608 ****
--- 2617,2631 ----
ZeroMemory(&ctx, sizeof(CONTEXT));
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
GetThreadContext(rb_MainThreadHandle, &ctx);
+ ctx_orig = ctx;
#ifdef _M_IX86
{
+ #if 0
DWORD *esp = (DWORD *)(ctx.Esp - sizeof(CONTEXT));
*(CONTEXT *)esp = ctx;
+ #else
+ DWORD *esp = (DWORD *)ctx.Esp;
+ #endif
*--esp = (DWORD)handler;
*--esp = arg;
*--esp = ctx.Eip;
***************
*** 2616,2622 ****
--- 2639,2652 ----
ctx.ContextFlags = CONTEXT_CONTROL;
SetThreadContext(rb_MainThreadHandle, &ctx);
}
+ ResetEvent(hEvent_win32_call_hander1);
ResumeThread(rb_MainThreadHandle);
+ WaitForSingleObject(hEvent_win32_call_hander1,INFINITE);
+ #undef Sleep
+ Sleep(0); // 安全ではないけど。
+ ctx_orig.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
+ SetThreadContext(rb_MainThreadHandle, &ctx_orig);
+ SetEvent(hEvent_win32_call_hander2);
return TRUE;
}
Sleep(0) は他のスレッドに動作を譲る働きをしますが、Sleep() 自体が
マクロで定義されてますし(^^;
# 私としてはかなりうんざりしてて、SIGINT 関連にもう手を出すのは
# 止めようと思ってます(^^;;
--
青木大輔 <dai@y7.net>