[#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:10794] Re: ruby-1.6.0-20000824.i586-mswin32 bug

From: "Nobuyoshi.Nakada" <nobu.nakada@...>
Date: 2000-09-01 12:08:33 UTC
List: ruby-dev #10794
なかだです。

At Fri, 1 Sep 2000 01:10:25 +0900
arton <arton@geocities.co.jp> wrote:
> やっと、家に帰れた...というくらい、今、忙しくて、全然検証できないんです
> が、

  いやはや。お疲れさまです(^^;。

> > +    {
> > +       DWORD* esp = (DWORD *)(con.Esp - sizeof(CONTEXT));
> > +       *(CONTEXT *)esp = con;
> > +       *--esp = (DWORD)handler;
> > +       *--esp = arg;
> > +       *--esp = (DWORD)abort; /* never reached */
> > +       con.Esp = (DWORD)esp;
> ここ、うまいなぁ、と思ったけど、考えてみたら、他のスレッドのスタックはい
> じれないのでした。

  え、そうなんですか。デバッガで追ってみると win32_call_handler() には正
しく渡っているものの、最後に SetThreadContext() した後でレジスタが変わっ
てるように見えたんですが。

> (レジスターはCONTEXTに入ってますが、うまい復帰方法は考え付かないので、
> とりあえずsignalの引数相当の分だけスタティック変数に突っ込んで、スタティ
> ック変数からシグナル関数に入る関数(ややこしい)にメインスレッドを突っ込
> んそこから、どこかに飛ばせないでしょうか?)
> ・その中でスレッド作らせて、自分をsuspendさせ、CONTEXTを再度設定させて、
> resumeさせるとかかな?

  これって、自分のスレッドに(当然動いてる状態で) SetThreadContext() はで
きないってことでしょうか。一応それも考えて割り込みのスレッドに通知して 
後始末させるっていうのも試したんですが、やっぱり con.Eip に戻ったところ
でレジスタが変わってしまっているような。メインのスタックを使わずにスタテ
ィック変数を使うようにしても同じです。

  ほとんどお手上げ。


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	Fri Sep  1 21:00:53 2000
@@ -75,6 +75,21 @@ IsWinNT(void) {
     return (IdOS() == VER_PLATFORM_WIN32_NT);
 }
 
+/* main thread constants */
+HANDLE rb_CurrentProcessHandle;
+HANDLE rb_MainThreadHandle;
+DWORD rb_MainThreadId;
+
+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 */
 
@@ -165,6 +180,10 @@ NtInitialize(int *argc, char ***argv) {
     WORD version;
     int ret;
 
+    rb_CurrentProcessHandle = GetCurrentProcess();
+    rb_MainThreadHandle = GetCurrentThreadHandle();
+    rb_MainThreadId = GetCurrentThreadId();
+
     //
     // subvert cmd.exe\'s feeble attempt at command line parsing
     //
@@ -2504,4 +2523,101 @@ mytimes(struct tms *tmbuf)
 	tmbuf->tms_cstime = 0;
     }
     return 0;
+}
+
+static void
+win32_suspend_self(void)
+{
+    SuspendThread(GetCurrentThread());
+}
+
+#define STATIC_ARGUMENTS
+#ifdef STATIC_ARGUMENTS
+#define INT(x) win32_int_##x
+static int INT(arg);
+static void (*INT(handler))(int);
+static HANDLE INT(ev);
+static volatile int INT(status);
+#define win32_int_statusp &win32_int_status
+#else
+#define INT(x) x
+#endif
+
+static void
+win32_call_handler(
+#ifdef STATIC_ARGUMENTS
+    void
+#else
+    int arg, void (*handler)(int), HANDLE ev, volatile int* statusp
+#endif
+)
+{
+    (void)rb_protect((VALUE (*)())INT(handler), (VALUE)INT(arg), INT(statusp));
+    SetEvent(INT(ev));
+    if (*INT(statusp)) rb_jump_tag(*INT(statusp));
+    win32_suspend_self();
+}
+
+int
+win32_main_context(int arg, void (*handler)(int))
+{
+    CONTEXT con;
+#ifndef STATIC_ARGUMENTS
+    HANDLE ev;
+    volatile int status = 0;
+#endif
+#ifdef _M_IX86
+    DWORD old_esp, old_eip;
+#else
+#error
+#endif
+
+    if (GetCurrentThreadId() == rb_MainThreadId) return FALSE;
+
+#ifdef STATIC_ARGUMENTS
+    INT(arg) = arg;
+    INT(handler) = handler;
+#endif
+    SuspendThread(rb_MainThreadHandle);
+    ZeroMemory(&con, sizeof(CONTEXT));
+    con.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
+    GetThreadContext(rb_MainThreadHandle, &con);
+    INT(ev) = CreateEvent(NULL, FALSE, FALSE, NULL);
+#ifdef _M_IX86
+    old_eip = con.Eip;
+    old_esp = con.Esp;
+#ifndef STATIC_ARGUMENTS
+    {
+	DWORD *esp = (DWORD *)old_esp;
+	*--esp = (DWORD)&status;
+	*--esp = (DWORD)ev;
+	*--esp = (DWORD)handler;
+	*--esp = arg;
+	*--esp = (DWORD)win32_suspend_self; /* main thread stops here */
+	con.Esp = (DWORD)esp;
+    }
+#endif
+    con.Eip = (DWORD)win32_call_handler;
+#else
+#error
+#endif
+
+    con.ContextFlags = CONTEXT_CONTROL;
+    SetThreadContext(rb_MainThreadHandle, &con);
+    ResumeThread(rb_MainThreadHandle);
+
+    WaitForSingleObject(INT(ev), INFINITE);
+    CloseHandle(INT(ev));
+
+    if (!INT(status)) {
+	SuspendThread(rb_MainThreadHandle);
+	con.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
+#ifdef _M_IX86
+	con.Eip = old_eip;
+	con.Esp = old_esp;
+#endif
+	SetThreadContext(rb_MainThreadHandle, &con);
+	ResumeThread(rb_MainThreadHandle);
+    }
+    return TRUE;
 }
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	Fri Sep  1 21:06:00 2000
@@ -426,4 +426,14 @@ struct tms {
 #endif
 #define times mytimes
 
+/* thread stuff */
+/* initialized by NtInitialize() */
+HANDLE rb_CurrentProcessHandle;
+HANDLE rb_MainThreadHandle;
+DWORD rb_MainThreadId;
+
+HANDLE GetCurrentThreadHandle(void);
+int win32_main_context(int arg, void (*handler)(int));
+
+
 #endif


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


In This Thread