[Top][All Lists]
[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);