[#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:11326] Re: SIGINT on windows
なかだです。
At Sun, 29 Oct 2000 23:38:53 +0900
Daisuke Aoki <dai@sweetparty.ne.jp> wrote:
> で、Windows 95 では flock() は大丈夫っぽそうです。って、これは
> USE_WAITEVENT を 95 にしていない場合です。USE_WAITEVENT と
> USE_CRITICALSECTION は 95 にすると、Windows 95 だとシグナル処理時に
> タイミング的に止まる可能性があるという問題を確認しました。ふつうに
> 使っていれば止まらないですけど(止まるとは、Ctrl+Alt+del で Ruby を
> 終わらせないとOS 自体が止まった状況になる現象です。)
考えてみたら、win32_asynchronize() は USE_WAITEVENT が有効の状態じゃな
きゃまったく意味ありませんね。ということで win32_asynchronize() にもシス
テムのチェックを入れました。
> あと、Windows 95 では、シグナル処理が連続で呼ばれるとだめみたいなので
> (例えば、Ctrl-C を押しっぱなしにすると止まる、回避のための対策に
> 成功しなかった)、以下を入れてください。Sleep(200) ですが、
> タイムスライスの msec の設定に依存するのかもしれませんけど、
> もっと大きい方がいいのかな。
優先度の高い signal thread 同士が win32_disable_interrupt() で実行権を
取り合って、他のプロセスにまで回らないということかな。以前優先度を下げて
もダメだったということですが、win32_disable_interrupt() の Sleep() を長
めにしてもダメでしたか。
NT でも SuspendThread() の前に優先度を下げちゃうと SuspendThread() で
きなくなるし。いやー難しいな。> Windows
つーことで[ruby-dev:11302]からの差分です。
--- win32/win32.c- Fri Oct 27 14:41:42 2000
+++ win32/win32.c Mon Oct 30 12:54:04 2000
@@ -43,4 +43,8 @@
#endif /* USE_CRITICALSECTION */
+#if !USE_WAITEVENT
+#undef USE_INTERRUPT_WINSOCK
+#endif /* !USE_WAITEVENT */
+
#ifdef WIN32_DEBUG
#define Debug(something) something
@@ -98,5 +102,7 @@
/* interrupt stuff */
+#if USE_WAITEVENT
static HANDLE interrupted_event;
+#endif /* USE_WAITEVENT */
HANDLE GetCurrentThreadHandle(void)
@@ -1974,5 +1980,6 @@
return file_nfds;
}
-#ifdef USE_INTERRUPT_WINSOCK
+
+#if USE_INTERRUPT_WINSOCK
if (ex)
trap = *ex;
@@ -1984,4 +1991,5 @@
ex = &trap;
#endif /* USE_INTERRUPT_WINSOCK */
+
if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
errno = WSAGetLastError();
@@ -2027,11 +2035,16 @@
main_thread.handle = GetCurrentThreadHandle();
main_thread.id = GetCurrentThreadId();
-#ifdef USE_INTERRUPT_WINSOCK
- interrupted_event = (HANDLE)WSACreateEvent();
-#else /* USE_INTERRUPT_WINSOCK */
- interrupted_event = CreateEvent(NULL, FALSE, FALSE, NULL);
-#endif /* USE_INTERRUPT_WINSOCK */
- if (!interrupted_event)
- rb_fatal("Unable to create interrupt event!\n");
+#if USE_WAITEVENT
+ if (USE_WAITEVENT == 95 || IsWinNT()) {
+# if USE_INTERRUPT_WINSOCK
+ interrupted_event = (HANDLE)WSACreateEvent();
+# else /* USE_INTERRUPT_WINSOCK */
+ interrupted_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+# endif /* USE_INTERRUPT_WINSOCK */
+
+ if (!interrupted_event)
+ rb_fatal("Unable to create interrupt event!\n");
+ }
+#endif /* USE_WAITEVENT */
}
@@ -2618,11 +2631,12 @@
events[count++] = interrupted_event;
-# ifdef USE_INTERRUPT_WINSOCK
+# if USE_INTERRUPT_WINSOCK
ret = WSAWaitForMultipleEvents(count, events, FALSE, timeout, TRUE);
# else /* USE_INTERRUPT_WINSOCK */
ret = WaitForMultipleObjects(count, events, FALSE, timeout);
# endif /* USE_INTERRUPT_WINSOCK */
+
if (ret == WAIT_OBJECT_0 + count - 1) {
-# ifdef USE_INTERRUPT_WINSOCK
+# if USE_INTERRUPT_WINSOCK
WSAResetEvent(interrupted_event);
# endif /* USE_INTERRUPT_WINSOCK */
@@ -2639,5 +2653,5 @@
} else {
Sleep(timeout);
- return FALSE;
+ return WAIT_TIMEOUT;
}
#endif /* USE_WAITEVENT != 95 */
@@ -2755,12 +2769,20 @@
struct handler_arg_t harg;
CONTEXT ctx_orig;
+ HANDLE current_thread = GetCurrentThread();
+ int old_priority = GetThreadPriority(current_thread);
-#ifdef USE_INTERRUPT_WINSOCK
+ if (GetCurrentThreadId() == main_thread.id) return FALSE;
+
+#if USE_WAITEVENT
+# if USE_INTERRUPT_WINSOCK
WSASetEvent(interrupted_event);
-#else /* USE_INTERRUPT_WINSOCK */
+# else /* USE_INTERRUPT_WINSOCK */
SetEvent(interrupted_event);
-#endif /* USE_INTERRUPT_WINSOCK */
+# endif /* USE_INTERRUPT_WINSOCK */
+#endif
- if (GetCurrentThreadId() == main_thread.id) return FALSE;
+ if (!IsWinNT()) {
+ Sleep(200); /* for safety on Windows 9x */
+ }
RUBY_CRITICAL({ /* the main thread must be in user state */
@@ -2768,4 +2790,5 @@
SuspendThread(main_thread.handle);
+ SetThreadPriority(current_thread, GetThreadPriority(main_thread.handle));
ZeroMemory(&ctx, sizeof(CONTEXT));
@@ -2789,30 +2812,23 @@
});
- {
- HANDLE current_thread = GetCurrentThread();
- int old_priority = GetThreadPriority(current_thread);
-
- /* give a chance to the main thread */
- SetThreadPriority(current_thread, GetThreadPriority(main_thread.handle));
- yield_once();
- WaitForSingleObject(interrupt_done, INFINITE); /* handshaking */
+ /* give a chance to the main thread */
+ yield_once();
+ WaitForSingleObject(interrupt_done, INFINITE); /* handshaking */
+ if (!harg.status) {
+ /* no exceptions raised, restore old context. */
RUBY_CRITICAL(
- if (!harg.status) {
- /* no exceptions raised, restore old context. */
+ /* ensure the main thread is in user state. */
+ yield_until(harg.userstate);
- /* ensure the main thread is in user state. */
- yield_until(harg.userstate);
-
- SuspendThread(main_thread.handle);
- ctx_orig.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
- SetThreadContext(main_thread.handle, &ctx_orig);
- ResumeThread(main_thread.handle);
- }
- /* otherwise leave the main thread raised */
+ SuspendThread(main_thread.handle);
+ ctx_orig.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
+ SetThreadContext(main_thread.handle, &ctx_orig);
+ ResumeThread(main_thread.handle);
);
-
- SetThreadPriority(current_thread, old_priority);
}
+ /* otherwise leave the main thread raised */
+
+ SetThreadPriority(current_thread, old_priority);
return TRUE;
@@ -2824,11 +2840,14 @@
}
-#define catch_interrupt win32_sleep
-
-void win32_enter_syscall(void)
+static void catch_interrupt(void)
{
yield_once();
- catch_interrupt(0);
+ win32_sleep(0);
CHECK_INTS;
+}
+
+void win32_enter_syscall(void)
+{
+ catch_interrupt();
win32_disable_interrupt();
}
@@ -2837,9 +2856,8 @@
{
win32_enable_interrupt();
- yield_once();
- catch_interrupt(0);
- CHECK_INTS;
+ catch_interrupt();
}
+#if USE_WAITEVENT
struct asynchronous_arg_t {
/* output field */
@@ -2860,67 +2878,76 @@
return (DWORD)arg->func(arg->self, arg->argc, arg->argv);
}
+#endif /* USE_WAITEVENT */
VALUE win32_asynchronize(asynchronous_func_t func,
VALUE self, int argc, VALUE* argv, VALUE intrval)
{
- DWORD val;
- BOOL interrupted = FALSE;
- HANDLE thr;
+#if USE_WAITEVENT
+ if (USE_WAITEVENT == 95 || IsWinNT()) {
+ DWORD val;
+ BOOL interrupted = FALSE;
+ HANDLE thr;
- RUBY_CRITICAL({
- struct asynchronous_arg_t arg;
+ RUBY_CRITICAL({
+ struct asynchronous_arg_t arg;
- arg.stackaddr = NULL;
- arg.func = func;
- arg.self = self;
- arg.argc = argc;
- arg.argv = argv;
+ arg.stackaddr = NULL;
+ arg.func = func;
+ arg.self = self;
+ arg.argc = argc;
+ arg.argv = argv;
- thr = CreateThread(NULL, 0, call_asynchronous, &arg, 0, &val);
+ thr = CreateThread(NULL, 0, call_asynchronous, &arg, 0, &val);
- if (thr) {
- yield_until(arg.stackaddr);
+ if (thr) {
+ yield_until(arg.stackaddr);
- if (wait_events(thr, INFINITE) != WAIT_OBJECT_0) {
- interrupted = TRUE;
+ if (wait_events(thr, INFINITE) != WAIT_OBJECT_0) {
+ interrupted = TRUE;
- if (TerminateThread(thr, intrval)) {
- yield_once();
- }
+ if (TerminateThread(thr, intrval)) {
+ yield_once();
+ }
- val = intrval;
- }
- else {
- GetExitCodeThread(thr, &val);
- }
+ val = intrval;
+ }
+ else {
+ GetExitCodeThread(thr, &val);
+ }
- CloseHandle(thr);
+ CloseHandle(thr);
- if (interrupted) {
- /* must release stack of killed thread, why Windows doesn't do this? */
- MEMORY_BASIC_INFORMATION m;
-
- memset(&m, 0, sizeof(m));
- if (!VirtualQuery(arg.stackaddr, &m, sizeof(m))) {
- Debug(fprintf(stderr, "couldn't get stack base:%p:%d\n",
- arg.stackaddr, GetLastError()));
- }
- else if (!VirtualFree(m.AllocationBase, 0, MEM_RELEASE)) {
- Debug(fprintf(stderr, "couldn't release stack:%p:%d\n",
- m.AllocationBase, GetLastError()));
+ if (interrupted) {
+ /* must release stack of killed thread, why doesn't Windows? */
+ MEMORY_BASIC_INFORMATION m;
+
+ memset(&m, 0, sizeof(m));
+ if (!VirtualQuery(arg.stackaddr, &m, sizeof(m))) {
+ Debug(fprintf(stderr, "couldn't get stack base:%p:%d\n",
+ arg.stackaddr, GetLastError()));
+ }
+ else if (!VirtualFree(m.AllocationBase, 0, MEM_RELEASE)) {
+ Debug(fprintf(stderr, "couldn't release stack:%p:%d\n",
+ m.AllocationBase, GetLastError()));
+ }
}
}
+ });
+
+ if (!thr) {
+ rb_fatal("failed to launch waiter thread:%d", GetLastError());
}
- });
- if (!thr) {
- rb_fatal("failed to launch waiter thread:%d", GetLastError());
- }
+ if (interrupted) {
+ errno = EINTR;
+ CHECK_INTS;
+ }
- if (interrupted) {
- errno = EINTR;
- CHECK_INTS;
+ return val;
}
+#endif /* USE_WAITEVENT */
- return val;
+#if USE_WAITEVENT != 95
+ return func(self, argc, argv);
+#endif /* USE_WAITEVENT != 95 */
}
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦