[#10793] 今度こそ (patch of the ruby-1.4.6 for NT4.0&VC4.0 on DEC Alpha.) — kou@...1609.sip.eee.yamaguchi-u.ac.jp (Koichi Okada)

岡田です。

10 messages 2000/09/01

[#10920] SIGINT on windows — "Nobuyoshi.Nakada" <nobu.nakada@...>

なかだです。

17 messages 2000/09/14
[#11077] Re: SIGINT on windows — matz@... (Yukihiro Matsumoto) 2000/09/27

まつもと ゆきひろです

[#10944] dummy DLL on Windows — "Nobuyoshi.Nakada" <nobu.nakada@...>

なかだです。

19 messages 2000/09/18
[#10955] Re: dummy DLL on Windows — WATANABE Hirofumi <eban@...> 2000/09/19

わたなべです.

[#10963] Re: dummy DLL on Windows — "Nobuyoshi.Nakada" <nobu.nakada@...> 2000/09/19

なかだです。

[#10964] Re: dummy DLL on Windows — WATANABE Hirofumi <eban@...> 2000/09/19

わたなべです.

[#10978] [PATCH] require in require — "Nobuyoshi.Nakada" <nobu.nakada@...>

なかだです。

15 messages 2000/09/20

[#10985] httphead.rb proxy version problem — Katsuyuki Komatsu <komatsu@...>

小松です.

16 messages 2000/09/20
[#10989] Re: httphead.rb proxy version problem — Minero Aoki <aamine@...> 2000/09/20

あおきです。

[ruby-dev:11077] Re: SIGINT on windows

From: matz@... (Yukihiro Matsumoto)
Date: 2000-09-27 03:40:59 UTC
List: ruby-dev #11077
まつもと ゆきひろです

In message "[ruby-dev:10920] SIGINT on windows"
    on 00/09/14, "Nobuyoshi.Nakada" <nobu.nakada@nifty.ne.jp> writes:

|  Windows 環境での SIGINT の件ですが、とりあえず試した限りでは落ちないよ
|うなので出してみます。どうも TRAP_BEG と TRAP_END がすっきりしないので、
|もしこれでうまくいくようなら rb_trap_immediate を置き換えるような形にし
|たほうのがいいのかも。
|
|# ついでに myselect() の中で rb_InterruptEvent も一緒に待つようにしてみ
|# たものの、これって正しいのかちと不安。

今日1.6.1をリリースします。で、できればこのパッチを含めたい
のですが、私のところでは検証できません。どなたか、最新のCVS 
に対してこのパッチを当てて、今日の夕方くらいまでに検証してい
ただける方はいらっしゃいませんでしょうか?

いらっしゃらなければ(バグレポートも来てるので)残念ですが、取
り込みは見送りです。やはり自分で検証できないものには慎重になっ
ちゃうなあ。

diff -pruPX ./.excludes current/rubysig.h devel/rubysig.h
--- current/rubysig.h	Mon May  1 18:41:29 2000
+++ devel/rubysig.h	Tue Sep 12 20:53:06 2000
@@ -14,8 +14,13 @@
 #define SIG_H
 
 EXTERN int rb_trap_immediate;
+#ifdef NT
+#define TRAP_BEG (rb_trap_immediate=1, SetEvent(rb_InterruptEvent))
+#define TRAP_END (rb_trap_immediate=0, ResetEvent(rb_InterruptEvent))
+#else
 #define TRAP_BEG (rb_trap_immediate=1)
 #define TRAP_END (rb_trap_immediate=0)
+#endif
 
 EXTERN int rb_prohibit_interrupt;
 #define DEFER_INTS {rb_prohibit_interrupt++;}
diff -pruPX ./.excludes current/signal.c devel/signal.c
--- current/signal.c	Mon Aug  7 14:01:57 2000
+++ devel/signal.c	Wed Sep 13 09:36:45 2000
@@ -341,6 +341,14 @@ static RETSIGTYPE
 sighandle(sig)
     int sig;
 {
+#ifdef NT
+#define end_interrupt() win32_thread_resume_main()
+    if (win32_main_context(sig, sighandle)) return;
+
+#else
+#define end_interrupt() (void)0
+#endif
+
     if (sig >= NSIG) {
 	rb_bug("trap_handler: Bad signal %d", sig);
     }
@@ -358,6 +366,7 @@ sighandle(sig)
 	rb_trap_pending++;
 	trap_pending_list[sig]++;
     }
+    end_interrupt();
 }
 
 #ifdef SIGBUS
diff -pruPX ./.excludes current/win32/win32.h devel/win32/win32.h
--- current/win32/win32.h	Tue Aug 15 15:22:49 2000
+++ devel/win32/win32.h	Tue Sep 12 20:53:03 2000
@@ -143,7 +143,7 @@ extern "C++" {
 #define execvp	   _execvp
 #define execvpe    _execvpe
 #define getpid	   _getpid
-#define sleep(x)   Sleep((x)*1000)
+#define sleep(x)   win32_sleep((x)*1000)
 #define spawnl	   _spawnl
 #define spawnle    _spawnle
 #define spawnlp    _spawnlp
@@ -425,5 +425,19 @@ struct tms {
 #undef times
 #endif
 #define times mytimes
+
+/* thread stuff */
+/* initialized by NtInitialize() */
+HANDLE rb_CurrentProcessHandle;
+HANDLE rb_MainThreadHandle;
+HANDLE rb_InterruptEvent;
+DWORD rb_MainThreadId;
+
+HANDLE GetCurrentThreadHandle(void);
+int win32_main_context(int arg, void (*handler)(int));
+int win32_interruptible(void);
+void win32_thread_resume_main(void);
+void win32_sleep(unsigned long msec);
+#define Sleep(msec) win32_sleep(msec)
 
 #endif
diff -pruPX ./.excludes current/win32/win32.c devel/win32/win32.c
--- current/win32/win32.c	Fri Sep  1 12:31:05 2000
+++ devel/win32/win32.c	Thu Sep 14 18:30:30 2000
@@ -75,6 +75,22 @@
     return (IdOS() == VER_PLATFORM_WIN32_NT);
 }
 
+/* main thread constants */
+HANDLE rb_CurrentProcessHandle;
+HANDLE rb_MainThreadHandle;
+DWORD rb_MainThreadId;
+HANDLE rb_InterruptEvent;
+
+HANDLE GetCurrentThreadHandle(void)
+{
+    HANDLE h;
+    HANDLE proc = rb_CurrentProcessHandle;
+
+    if (!DuplicateHandle(proc, GetCurrentThread(), proc, &h,
+			 0, FALSE, DUPLICATE_SAME_ACCESS))
+	return NULL;
+    return h;
+}
 
 /* simulate flock by locking a range on the file */
 
@@ -160,7 +176,8 @@
 // Initialization stuff
 //
 void
-NtInitialize(int *argc, char ***argv) {
+NtInitialize(int *argc, char ***argv)
+{
 
     WORD version;
     int ret;
@@ -1211,7 +1228,7 @@
 //
 
 DIR *
-opendir(const char *filename)
+opendir(char *filename)
 {
     DIR            *p;
     long            len;
@@ -1879,6 +1896,7 @@
     long r;
     fd_set file_rd;
     fd_set file_wr;
+    fd_set trap;
     int file_nfds;
     int trap_immediate = rb_trap_immediate;
 
@@ -1899,9 +1917,16 @@
 	if (wr) *wr = file_wr;
 	return file_nfds;
     }
+    if (ex)
+	trap = *ex;
+    else
+	trap.fd_count = 0;
+    if (trap.fd_count < FD_SETSIZE)
+	trap.fd_array[trap.fd_count++] = rb_InterruptEvent;
+    // else unable to catch interrupt.
     if (trap_immediate)
 	TRAP_END;
-    if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
+    if ((r = select (nfds, rd, wr, &trap, timeout)) == SOCKET_ERROR) {
 	errno = WSAGetLastError();
 	switch (errno) {
 	case WSAEINTR:
@@ -1915,7 +1940,8 @@
 }
 
 static void
-StartSockets () {
+StartSockets ()
+{
     WORD version;
     WSADATA retdata;
     int ret;
@@ -1942,6 +1968,11 @@
      */
     setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
 		(char *)&iSockOpt, sizeof(iSockOpt));
+
+    rb_CurrentProcessHandle = GetCurrentProcess();
+    rb_MainThreadHandle = GetCurrentThreadHandle();
+    rb_MainThreadId = GetCurrentThreadId();
+    rb_InterruptEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
 }
 
 #undef accept
@@ -2504,4 +2535,91 @@
 	tmbuf->tms_cstime = 0;
     }
     return 0;
+}
+
+
+static int win32_thread_exclusive(void)
+{
+    if (GetCurrentThreadId() == rb_MainThreadId) return FALSE;
+
+    SuspendThread(rb_MainThreadHandle);
+    return TRUE;
+}
+
+void win32_thread_resume_main(void)
+{
+    if (GetCurrentThreadId() != rb_MainThreadId)
+	ResumeThread(rb_MainThreadHandle);
+}
+
+static void win32_suspend_self(void)
+{
+    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)
+{
+    return !WaitForSingleObject(rb_InterruptEvent, msec);
+}
+
+int win32_interruptible(void)
+{
+    if (catch_interrupt(0)) return TRUE;
+    SetEvent(rb_InterruptEvent);
+    return FALSE;
+}
+
+int win32_main_context(int arg, void (*handler)(int))
+{
+    if (!win32_thread_exclusive()) return FALSE;
+
+    if (!catch_interrupt(0)) {
+	SetEvent(rb_InterruptEvent);
+	return FALSE;
+    }
+
+    {
+	CONTEXT ctx;
+
+	ZeroMemory(&ctx, sizeof(CONTEXT));
+	ctx.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
+	GetThreadContext(rb_MainThreadHandle, &ctx);
+#ifdef _M_IX86
+	{
+	    DWORD *esp = (DWORD *)(ctx.Esp - sizeof(CONTEXT));
+	    *(CONTEXT *)esp = ctx;
+	    *--esp = (DWORD)handler;
+	    *--esp = arg;
+	    *--esp = ctx.Eip;
+	    ctx.Esp = (DWORD)esp;
+	}
+	ctx.Eip = (DWORD)win32_call_handler;
+#else
+#error
+#endif
+
+	ctx.ContextFlags = CONTEXT_CONTROL;
+	SetThreadContext(rb_MainThreadHandle, &ctx);
+    }
+    ResumeThread(rb_MainThreadHandle);
+
+    return TRUE;
+}
+
+void win32_sleep(unsigned long msec)
+{
+    int trap_immediate = rb_trap_immediate;
+
+    if (trap_immediate)
+	TRAP_END;
+    catch_interrupt(msec);
+    if (trap_immediate)
+	TRAP_BEG;
 }

In This Thread