On Tue, 14 Mar 2000, Ove Kaaven wrote:
>...
> 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
>
How about this
a) Don't set FD_CLOSE in sock->pmask on POLLHUP for normal data flow
if recv( ..., MSG_PEEK) returns > 0. Disable polling for this socket.
b) In the reenabler for FD_READ event, if WS_FD_CONNECTED is missing,
FD_CLOSE is not present in sock->pmask and recv( ..., MSG_PEEK)
returns zero or less then set sock->pmask to FD_CLOSE and do
set_event(sock->event) to deliver it.
Alex
--- sock.c Fri Dec 31 19:56:28 1999
+++ sock.new.c Wed Mar 15 00:42:51 2000
@@ -168,17 +168,23 @@
}
if (event & (POLLERR|POLLHUP))
{
+ unsigned n;
sock->errors[FD_CLOSE_BIT] = sock_error( sock->obj.fd );
/* we got an error, socket closing? */
sock->state &= ~(WS_FD_CONNECTED|WS_FD_READ|WS_FD_WRITE);
- sock->pmask |= FD_CLOSE;
+ if( recv( sock->obj.fd, &n, 1, MSG_PEEK ) <= 0 )
+ sock->pmask |= FD_CLOSE;
if (debug_level)
fprintf(stderr, "socket %d aborted by error %d\n",
sock->obj.fd, sock->errors[FD_CLOSE_BIT]);
}
}
- sock_reselect( sock );
+ if( event & (POLLERR|POLLHUP) )
+ 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)
@@ -498,10 +504,22 @@
sock=(struct
sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops);
if (!sock)
return;
+
sock->pmask &= ~req->mask; /* is this safe? */
sock->hmask &= ~req->mask;
sock->state |= req->sstate;
sock->state &= ~req->cstate;
- sock_reselect( sock );
+
+ if( (req->mask & FD_READ) && !(sock->state & WS_FD_CONNECTED) )
+ {
+ unsigned n;
+ if( recv( sock->obj.fd, &n, 1, MSG_PEEK) <= 0 )
+ sock->pmask |= sock->mask & FD_CLOSE;
+ else
+ sock->pmask |= sock->mask & FD_READ;
+ set_event( sock->event );
+ }
+ else
+ sock_reselect( sock );
release_object( &sock->obj );
}