diff src/w32.c @ 71899:6772d0603863

(pfn_WSACreateEvent, pfn_WSACloseEvent): New func ptrs. (init_winsock): Load them. Use ws2_32.dll. (sys_listen): Undo last change. Just set FILE_LISTEN flag. (sys_accept): Undo last change. Instead, set child status to STATUS_READ_ACKNOWLEDGED and reset char_avail event so next sys_select will wakeup the reader thread. (_sys_wait_accept): New function used by reader thread to wait for an incoming connection on a server socket.
author Kim F. Storm <storm@cua.dk>
date Fri, 14 Jul 2006 14:18:40 +0000
parents 2385a5c8186c
children 7b3a19a8bfdb 8a8e69664178
line wrap: on
line diff
--- a/src/w32.c	Fri Jul 14 12:05:02 2006 +0000
+++ b/src/w32.c	Fri Jul 14 14:18:40 2006 +0000
@@ -2701,6 +2701,8 @@
 void (PASCAL *pfn_WSASetLastError) (int iError);
 int (PASCAL *pfn_WSAGetLastError) (void);
 int (PASCAL *pfn_WSAEventSelect) (SOCKET s, HANDLE hEventObject, long lNetworkEvents);
+HANDLE (PASCAL *pfn_WSACreateEvent) (void);
+int (PASCAL *pfn_WSACloseEvent) (HANDLE hEvent);
 int (PASCAL *pfn_socket) (int af, int type, int protocol);
 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
@@ -2770,7 +2772,7 @@
     = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
 			       "SetHandleInformation");
 
-  winsock_lib = LoadLibrary ("wsock32.dll");
+  winsock_lib = LoadLibrary ("Ws2_32.dll");
 
   if (winsock_lib != NULL)
     {
@@ -2784,6 +2786,8 @@
       LOAD_PROC( WSASetLastError );
       LOAD_PROC( WSAGetLastError );
       LOAD_PROC( WSAEventSelect );
+      LOAD_PROC( WSACreateEvent );
+      LOAD_PROC( WSACloseEvent );
       LOAD_PROC( socket );
       LOAD_PROC( bind );
       LOAD_PROC( connect );
@@ -3298,10 +3302,7 @@
       if (rc == SOCKET_ERROR)
 	set_errno ();
       else
-	{
-	  fd_info[s].flags |= FILE_LISTEN;
-	  pfn_WSAEventSelect (SOCK_HANDLE (s), fd_info[s].cp->char_avail, FD_ACCEPT);
-	}
+	fd_info[s].flags |= FILE_LISTEN;
       return rc;
     }
   h_errno = ENOTSOCK;
@@ -3342,16 +3343,15 @@
   if (fd_info[s].flags & FILE_LISTEN)
     {
       SOCKET t = pfn_accept (SOCK_HANDLE (s), addr, addrlen);
-      if (t != INVALID_SOCKET)
-	{
-	  int fd = socket_to_fd (t);
-	  if (fd >= 0)
-	    pfn_WSAEventSelect (SOCK_HANDLE (fd), fd_info[fd].cp->char_avail, FD_READ | FD_CLOSE);
-	  return fd;
-	}
-
-      set_errno ();
-      return -1;
+      int fd = -1;
+      if (t == INVALID_SOCKET)
+	set_errno ();
+      else
+	fd = socket_to_fd (t);
+
+      fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED;
+      ResetEvent (fd_info[s].cp->char_avail);
+      return fd;
     }
   h_errno = ENOTSOCK;
   return -1;
@@ -3653,6 +3653,36 @@
   return cp->status;
 }
 
+int _sys_wait_accept (int fd)
+{
+  HANDLE hEv;
+  child_process * cp;
+  int rc;
+
+  if (fd < 0 || fd >= MAXDESC)
+    return STATUS_READ_ERROR;
+
+  cp = fd_info[fd].cp;
+
+  if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
+    return STATUS_READ_ERROR;
+
+  cp->status = STATUS_READ_FAILED;
+
+  hEv = pfn_WSACreateEvent ();
+  rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT);
+  if (rc != SOCKET_ERROR)
+    {
+      rc = WaitForSingleObject (hEv, INFINITE);
+      pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0);
+      pfn_WSACloseEvent (hEv);
+      if (rc == WAIT_OBJECT_0)
+	cp->status = STATUS_READ_SUCCEEDED;
+    }
+
+  return cp->status;
+}
+
 int
 sys_read (int fd, char * buffer, unsigned int count)
 {