help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] [PATCH 2/2 RFT] support socket select in lib-src/socket


From: Paolo Bonzini
Subject: [Help-smalltalk] [PATCH 2/2 RFT] support socket select in lib-src/socketx.c's win_select
Date: Sun, 17 Aug 2008 15:34:03 +0200
User-agent: Thunderbird 2.0.0.16 (Macintosh/20080707)


2) Even though MsgWaitForMultipleObjects works for sockets, I guess GetFileType should be called earlier, so that the state of sockets is correctly returned as readable or writable or both.

The attached patch (not applied yet) tries to implement this. I have not even compiled it; help is appreciated.

Paolo
diff --git a/lib-src/socketx.c b/lib-src/socketx.c
index 64a9060..1be2e20 100644
--- a/lib-src/socketx.c
+++ b/lib-src/socketx.c
@@ -33,6 +33,8 @@ int
 win_select (int n, fd_set * rfds, fd_set * wfds, fd_set * efds,
            struct timeval *ptv)
 {
+  static struct timeval tv0;
+  static HANDLE hEvent;
   HANDLE handle_array[MAX_WIN_HANDLES];
   int handle_fd[MAX_WIN_HANDLES];
   fd_set *handle_set[MAX_WIN_HANDLES];
@@ -40,30 +42,65 @@ win_select (int n, fd_set * rfds, fd_set * wfds, fd_set * 
efds,
   int i, nset;
   BOOL bRet;
   MSG msg;
+  char sockbuf[256];
 
   _flushall ();
-  nhandles = 0;
+  if (!hEvent)
+    hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+  handle_array[nhandles] = hEvent;
+  handle_fd[nhandles] = 0;
+  handle_set[nhandles] = NULL;
+  nhandles = 1;
   for (i = 0; i < n; i++)
     {
-      if ((efds != NULL) && FD_ISSET (i, efds))
-       FD_CLR (i, efds);       /* assume no exceptions */
-
-      if ((wfds != NULL) && FD_ISSET (i, wfds))
+      int in_efds = 0, in_wfds = 0, in_rfds = 0;
+      int optlen;
+      HANDLE h;
+      if (efds && FD_ISSET (i, wfds))
+       in_efds = 1;
+      if (wfds && FD_ISSET (i, wfds))
+       in_wfds = 1;
+      if (rfds && FD_ISSET (i, rfds))
+       in_rfds = 1;
+
+      h = (HANDLE) _get_osfhandle (i);
+      optlen = sizeof(sockbuf);
+      if ((getsockopt ((SOCKET) h, SOL_SOCKET, SO_TYPE, sockbuf, &optlen)
+          != SOCKET_ERROR)
+         || WSAGetLastError() != WSAENOTSOCK)
        {
-         handle_array[nhandles] = (HANDLE) _get_osfhandle (i);
-         handle_fd[nhandles] = i;
-         handle_set[nhandles] = wfds;
-         nhandles++;
-         FD_CLR (i, wfds);     /* we will set it later if there is output */
+         int ev = 0;
+         if (in_rfds)
+           ev |= FD_READ | FD_ACCEPT;
+         if (in_wfds)
+           ev |= FD_WRITE | FD_CONNECT;
+         if (in_efds)
+           ev |= FD_OOB;
+         if (ev)
+           WSAEventSelect ((SOCKET) h, hEvent, ev);
        }
-
-      if ((rfds != NULL) && FD_ISSET (i, rfds))
+      else
        {
-         handle_array[nhandles] = (HANDLE) _get_osfhandle (i);
-         handle_fd[nhandles] = i;
-         handle_set[nhandles] = rfds;
-         nhandles++;
-         FD_CLR (i, rfds);     /* we will set it later if there is input */
+          if (in_efds)
+            FD_CLR (i, efds);
+
+         if (in_wfds)
+           {
+              FD_CLR (i, wfds);
+             handle_array[nhandles] = h;
+             handle_fd[nhandles] = i;
+             handle_set[nhandles] = wfds;
+             nhandles++;
+           }
+
+          if (in_rfds)
+           {
+              FD_CLR (i, rfds);
+             handle_array[nhandles] = h;
+             handle_fd[nhandles] = i;
+             handle_set[nhandles] = rfds;
+             nhandles++;
+           }
        }
     }
 
@@ -89,9 +126,10 @@ win_select (int n, fd_set * rfds, fd_set * wfds, fd_set * 
efds,
        }
     }
 
-  /* now do a quick poll of all handles to see how many are ready */
-  nset = 0;
-  for (i = 0; i < nhandles; i++)
+  /* now do a quick poll of all handles to see how many are ready; the first
+     handle is the WSAEventSelect handle */
+  nset = select (n, rfds, wfds, efds, tv0);
+  for (i = 1; i < nhandles; i++)
     {
       HANDLE h = handle_array[i];
       ret = WaitForSingleObject (h, 0);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]