On Mon, 13 Mar 2000, Matthew Cline wrote:
> The reason for the select being aborted is that the poll() reports
> the socket as being POLLHUP.
>
> I really have no clue as to what might be wrong, or how to track
> down the problem. Any help would be appreciated.
I would like concise documentation for poll() myself, but from what I've
been able to dig up, POLLHUP and POLLERR are nonmaskable and appears to be
fatal. POLLHUP probably has something to do with the socket being closed
or shut down (although I'm not sure from which side) so that it can no
longer be written to, but any remaining data can still be read from it.
The simple solution would be to stop polling the socket once a POLLHUP and
POLLERR are received, but this would fail to take into account any
remaining readable data. Consider this situation:
large quantities of data is shuffled and buffered
TCP channel is then shut down
wineserver events: POLLIN | POLLHUP
wineserver socket handler signals FD_READ | FD_CLOSE events, and disables
polling with set_select_events(sock,-1)
application receives notifications, notices FD_READ, and calls recv() to
read some of the data. recv() reads out the data and sends a reenable
request to wineserver to trigger further FD_READ notifications
wineserver socket handler receives reenable request and attempts to
reenable POLLIN. However, polling has been completely disabled and cannot
be reenabled using set_select_events(). As a consequence, no further
notifications will be sent.
application never gets to read any remaining data
Perhaps Alexandre has an idea how best to disable polling temporarily
rather than the permanent way set_select_events() do now.
Apart from this small problem, this patch might work, assuming that
POLLERR has the same behaviour as POLLHUP (which may not be the case).
Any poll()-over-sockets gurus around here?
Index: wine/server/sock.c
===================================================================
RCS file: /home/wine/wine/server/sock.c,v
retrieving revision 1.7
diff -u -r1.7 sock.c
--- wine/server/sock.c 2000/01/01 00:56:28 1.7
+++ wine/server/sock.c 2000/03/14 22:38:15
@@ -178,7 +178,12 @@
}
}
- sock_reselect( sock );
+ if (event & (POLLERR|POLLHUP))
+ /* FIXME: there may still be readable data waiting,
+ * which may not be re-signaled after we stop waiting! */
+ set_select_events( &sock->obj, -1 );
+ else
+ sock_reselect( sock );
/* wake up anyone waiting for whatever just happened */
emask = sock->pmask & sock->mask;
if (debug_level && emask)