[前][次][番号順一覧][スレッド一覧]

ruby-changes:6327

From: shyouhei <ko1@a...>
Date: Thu, 3 Jul 2008 17:17:14 +0900 (JST)
Subject: [ruby-changes:6327] Ruby:r17843 (ruby_1_8_6): * win32/win32.c: revert r17290, requested by NAKAMURA Usaku

shyouhei	2008-07-03 17:16:52 +0900 (Thu, 03 Jul 2008)

  New Revision: 17843

  Modified files:
    branches/ruby_1_8_6/ChangeLog
    branches/ruby_1_8_6/version.h
    branches/ruby_1_8_6/win32/win32.c

  Log:
    * win32/win32.c: revert r17290, requested by NAKAMURA Usaku
      <usa at ruby-lang.org>
    



  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=17843

Index: ruby_1_8_6/ChangeLog
===================================================================
--- ruby_1_8_6/ChangeLog	(revision 17842)
+++ ruby_1_8_6/ChangeLog	(revision 17843)
@@ -1,3 +1,8 @@
+Thu Jul  3 17:15:04 2008  URABE Shyouhei  <shyouhei@r...>
+
+	* win32/win32.c: revert r17290, requested by NAKAMURA Usaku
+	  <usa at ruby-lang.org>
+
 Wed Jul  2 19:05:35 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/cgi.rb (CGI::QueryExtension.read_multipart): blanks inside
Index: ruby_1_8_6/version.h
===================================================================
--- ruby_1_8_6/version.h	(revision 17842)
+++ ruby_1_8_6/version.h	(revision 17843)
@@ -1,15 +1,15 @@
 #define RUBY_VERSION "1.8.6"
-#define RUBY_RELEASE_DATE "2008-07-02"
+#define RUBY_RELEASE_DATE "2008-07-03"
 #define RUBY_VERSION_CODE 186
-#define RUBY_RELEASE_CODE 20080702
-#define RUBY_PATCHLEVEL 264
+#define RUBY_RELEASE_CODE 20080703
+#define RUBY_PATCHLEVEL 265
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
 #define RUBY_VERSION_TEENY 6
 #define RUBY_RELEASE_YEAR 2008
 #define RUBY_RELEASE_MONTH 7
-#define RUBY_RELEASE_DAY 2
+#define RUBY_RELEASE_DAY 3
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
Index: ruby_1_8_6/win32/win32.c
===================================================================
--- ruby_1_8_6/win32/win32.c	(revision 17842)
+++ ruby_1_8_6/win32/win32.c	(revision 17843)
@@ -369,7 +369,6 @@
 }
 #endif
 
-static CRITICAL_SECTION select_mutex;
 static BOOL fWinsock;
 static char *envarea;
 static void
@@ -383,7 +382,6 @@
 	FreeEnvironmentStrings(envarea);
 	envarea = NULL;
     }
-    DeleteCriticalSection(&select_mutex);
 }
 
 static void
@@ -472,8 +470,6 @@
 
     init_stdhandle();
 
-    InitializeCriticalSection(&select_mutex);
-
     atexit(exit_handler);
 
     // Initialize Winsock
@@ -2058,250 +2054,87 @@
 static int NtSocketsInitialized = 0;
 
 static int
-extract_fd(fd_set *dst, fd_set *src, int (*func)(SOCKET))
+extract_file_fd(fd_set *set, fd_set *fileset)
 {
-    int s = 0;
-    if (!src || !dst) return 0;
+    int idx;
 
-    while (s < src->fd_count) {
-        SOCKET fd = src->fd_array[s];
+    fileset->fd_count = 0;
+    if (!set)
+	return 0;
+    for (idx = 0; idx < set->fd_count; idx++) {
+	SOCKET fd = set->fd_array[idx];
 
-	if (!func || (*func)(fd)) { /* move it to dst */
-	    int d;
+	if (!is_socket(fd)) {
+	    int i;
 
-	    for (d = 0; d < dst->fd_count; d++) {
-		if (dst->fd_array[d] == fd) break;
+	    for (i = 0; i < fileset->fd_count; i++) {
+		if (fileset->fd_array[i] == fd) {
+		    break;
+		}
 	    }
-	    if (d == dst->fd_count && dst->fd_count < FD_SETSIZE) {
-		dst->fd_array[dst->fd_count++] = fd;
+	    if (i == fileset->fd_count) {
+		if (fileset->fd_count < FD_SETSIZE) {
+		    fileset->fd_array[i] = fd;
+		    fileset->fd_count++;
+		}
 	    }
-	    memmove(
-		&src->fd_array[s],
-		&src->fd_array[s+1], 
-		sizeof(src->fd_array[0]) * (--src->fd_count - s));
 	}
-	else s++;
     }
-
-    return dst->fd_count;
+    return fileset->fd_count;
 }
 
-static int
-is_not_socket(SOCKET sock)
-{
-    return !is_socket(sock);
-}
-
-static int
-is_pipe(SOCKET sock) /* DONT call this for SOCKET! it clains it is PIPE. */
-{
-    int ret;
-
-    RUBY_CRITICAL(
-	ret = (GetFileType((HANDLE)sock) == FILE_TYPE_PIPE)
-    );
-
-    return ret;
-}
-
-static int
-is_readable_pipe(SOCKET sock) /* call this for pipe only */
-{
-    int ret;
-    DWORD n = 0;
-
-    RUBY_CRITICAL(
-	if (PeekNamedPipe((HANDLE)sock, NULL, 0, NULL, &n, NULL)) {
-	    ret = (n > 0);
-	}
-	else {
-	    ret = (GetLastError() == ERROR_BROKEN_PIPE); /* pipe was closed */
-	}
-    );
-
-    return ret;
-}
-
-static int
-is_console(SOCKET sock) /* DONT call this for SOCKET! */
-{
-    int ret;
-    DWORD n = 0;
-    INPUT_RECORD ir;
-
-    RUBY_CRITICAL(
-	ret = (PeekConsoleInput((HANDLE)sock, &ir, 1, &n))
-    );
-
-    return ret;
-}
-
-static int
-is_readable_console(SOCKET sock) /* call this for console only */
-{
-    int ret = 0;
-    DWORD n = 0;
-    INPUT_RECORD ir;
-
-    RUBY_CRITICAL(
-	if (PeekConsoleInput((HANDLE)sock, &ir, 1, &n) && n > 0) {
-	    if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown &&
-		ir.Event.KeyEvent.uChar.AsciiChar) {
-		ret = 1;
-	    }
-	    else {
-		ReadConsoleInput((HANDLE)sock, &ir, 1, &n);
-	    }
-	}
-    );
-
-    return ret;
-}
-
-static int
-do_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
-            struct timeval *timeout)
-{
-    int r = 0;
-
-    if (nfds == 0) {
-	if (timeout)
-	    rb_w32_sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
-	else
-	    rb_w32_sleep(INFINITE);
-    }
-    else {
-	RUBY_CRITICAL(
-	    EnterCriticalSection(&select_mutex);
-	    r = select(nfds, rd, wr, ex, timeout);
-	    LeaveCriticalSection(&select_mutex);
-	    if (r == SOCKET_ERROR) {
-		errno = map_errno(WSAGetLastError());
-		r = -1;
-	    }
-	);
-    }
-
-    return r;
-}
-
-static inline int
-subst(struct timeval *rest, const struct timeval *wait)
-{
-    while (rest->tv_usec < wait->tv_usec) {
-	if (rest->tv_sec <= wait->tv_sec) {
-	    return 0;
-	}
-	rest->tv_sec -= 1;
-	rest->tv_usec += 1000 * 1000;
-    }
-    rest->tv_sec -= wait->tv_sec;
-    rest->tv_usec -= wait->tv_usec;
-    return 1;
-}
-
-static inline int
-compare(const struct timeval *t1, const struct timeval *t2)
-{
-    if (t1->tv_sec < t2->tv_sec)
-	return -1;
-    if (t1->tv_sec > t2->tv_sec)
-	return 1;
-    if (t1->tv_usec < t2->tv_usec)
-	return -1;
-    if (t1->tv_usec > t2->tv_usec)
-	return 1;
-    return 0;
-}
-
-#undef Sleep
 long 
 rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
 	       struct timeval *timeout)
 {
     long r;
-    fd_set pipe_rd;
-    fd_set cons_rd;
-    fd_set else_rd;
-    fd_set else_wr;
-    int nonsock = 0;
+    fd_set file_rd;
+    fd_set file_wr;
+#ifdef USE_INTERRUPT_WINSOCK
+    fd_set trap;
+#endif /* USE_INTERRUPT_WINSOCK */
+    int file_nfds;
 
-    if (nfds < 0 || (timeout && (timeout->tv_sec < 0 || timeout->tv_usec < 0))) {
-	errno = EINVAL;
-	return -1;
-    }
     if (!NtSocketsInitialized) {
 	StartSockets();
     }
-
-    // assume else_{rd,wr} (other than socket, pipe reader, console reader)
-    // are always readable/writable. but this implementation still has
-    // problem. if pipe's buffer is full, writing to pipe will block
-    // until some data is read from pipe. but ruby is single threaded system,
-    // so whole system will be blocked forever.
-
-    else_rd.fd_count = 0;
-    nonsock += extract_fd(&else_rd, rd, is_not_socket);
-
-    pipe_rd.fd_count = 0;
-    extract_fd(&pipe_rd, &else_rd, is_pipe); // should not call is_pipe for socket
-
-    cons_rd.fd_count = 0;
-    extract_fd(&cons_rd, &else_rd, is_console); // ditto
-
-    else_wr.fd_count = 0;
-    nonsock += extract_fd(&else_wr, wr, is_not_socket);
-
     r = 0;
     if (rd && rd->fd_count > r) r = rd->fd_count;
     if (wr && wr->fd_count > r) r = wr->fd_count;
     if (ex && ex->fd_count > r) r = ex->fd_count;
     if (nfds > r) nfds = r;
-
+    if (nfds == 0 && timeout) {
+	Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
+	return 0;
+    }
+    file_nfds = extract_file_fd(rd, &file_rd);
+    file_nfds += extract_file_fd(wr, &file_wr);
+    if (file_nfds)
     {
-	struct timeval rest;
-	struct timeval wait;
-	struct timeval zero;
-	if (timeout) rest = *timeout;
-	wait.tv_sec = 0; wait.tv_usec = 10 * 1000; // 10ms
-	zero.tv_sec = 0; zero.tv_usec = 0;         //  0ms
-	do {
-	    if (nonsock) {
-		// modifying {else,pipe,cons}_rd is safe because
-		// if they are modified, function returns immediately.
-		extract_fd(&else_rd, &pipe_rd, is_readable_pipe);
-		extract_fd(&else_rd, &cons_rd, is_readable_console);
-	    }
-
-	    if (else_rd.fd_count || else_wr.fd_count) {
-		r = do_select(nfds, rd, wr, ex, &zero); // polling
-		if (r < 0) break; // XXX: should I ignore error and return signaled handles?
-		r += extract_fd(rd, &else_rd, NULL); // move all
-		r += extract_fd(wr, &else_wr, NULL); // move all
-		break;
-	    }
-	    else {
-		struct timeval *dowait =
-		    compare(&rest, &wait) < 0 ? &rest : &wait;
-
-		fd_set orig_rd;
-		fd_set orig_wr;
-		fd_set orig_ex;
-		if (rd) orig_rd = *rd;
-		if (wr) orig_wr = *wr;
-		if (ex) orig_ex = *ex;
-		r = do_select(nfds, rd, wr, ex, &zero);	// polling
-		if (r != 0) break; // signaled or error
-		if (rd) *rd = orig_rd;
-		if (wr) *wr = orig_wr;
-		if (ex) *ex = orig_ex;
-
-		// XXX: should check the time select spent
-		Sleep(dowait->tv_sec * 1000 + dowait->tv_usec / 1000);
-	    }
-	} while (!timeout || subst(&rest, &wait));
+	// assume normal files are always readable/writable
+	// fake read/write fd_set and return value
+	if (rd) *rd = file_rd;
+	if (wr) *wr = file_wr;
+	return file_nfds;
     }
 
+#if USE_INTERRUPT_WINSOCK
+    if (ex)
+	trap = *ex;
+    else
+	trap.fd_count = 0;
+    if (trap.fd_count < FD_SETSIZE)
+	trap.fd_array[trap.fd_count++] = (SOCKET)interrupted_event;
+    // else unable to catch interrupt.
+    ex = &trap;
+#endif /* USE_INTERRUPT_WINSOCK */
+
+    RUBY_CRITICAL({
+	r = select(nfds, rd, wr, ex, timeout);
+	if (r == SOCKET_ERROR) {
+	    errno = map_errno(WSAGetLastError());
+	}
+    });
     return r;
 }
 
@@ -3436,6 +3269,7 @@
     return 0;
 }
 
+#undef Sleep
 #define yield_once() Sleep(0)
 #define yield_until(condition) do yield_once(); while (!(condition))
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]