Commit ec07f285 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

server: Separate SD_RECEIVE and hangup conditions.

This patch does result in one functional change: if we are selecting for AFD_POLL_READ on a socket which has had SD_RECEIVE and there are no asyncs, we will now respond to POLLIN instead of ignoring it. Neither this nor the previous behaviour matches Windows, which instead puts the socket into an aborted state and sends RST to the peer if any data is received after SD_RECEIVE or if SD_RECEIVE is done while there is pending data. Apart from this there is no functional change, as the places where rd_shutdown alone is checked can't be reached if there was a hangup. It is instead for semantic clarity. Signed-off-by: 's avatarZebediah Figura <zfigura@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent a9ddbc0c
......@@ -214,6 +214,7 @@ struct sock
unsigned int rd_shutdown : 1; /* is the read end shut down? */
unsigned int wr_shutdown : 1; /* is the write end shut down? */
unsigned int wr_shutdown_pending : 1; /* is a write shutdown pending? */
unsigned int hangup : 1; /* has the read end received a hangup? */
unsigned int nonblocking : 1; /* is the socket nonblocking? */
unsigned int bound : 1; /* is the socket bound? */
};
......@@ -930,7 +931,7 @@ static int sock_dispatch_asyncs( struct sock *sock, int event, int error )
int status = sock_get_ntstatus( error );
struct accept_req *req, *next;
if (sock->rd_shutdown)
if (sock->rd_shutdown || sock->hangup)
async_wake_up( &sock->read_q, status );
if (sock->wr_shutdown)
async_wake_up( &sock->write_q, status );
......@@ -1072,15 +1073,17 @@ static void sock_poll_event( struct fd *fd, int event )
}
}
if ((hangup_seen || event & (POLLHUP | POLLERR)) && (!sock->rd_shutdown || !sock->wr_shutdown))
if (hangup_seen || (sock_shutdown_type == SOCK_SHUTDOWN_POLLHUP && (event & POLLHUP)))
{
sock->hangup = 1;
}
else if (event & (POLLHUP | POLLERR))
{
error = error ? error : sock_error( fd );
if ( (event & POLLERR) || ( sock_shutdown_type == SOCK_SHUTDOWN_EOF && (event & POLLHUP) ))
sock->wr_shutdown = 1;
sock->rd_shutdown = 1;
sock->wr_shutdown = 1;
if (debug_level)
fprintf(stderr, "socket %p aborted by error %d, event: %x\n", sock, error, event);
fprintf( stderr, "socket %p aborted by error %d, event %#x\n", sock, error, event );
}
if (hangup_seen)
......@@ -1168,7 +1171,9 @@ static int sock_get_poll_events( struct fd *fd )
}
else
{
if (!sock->rd_shutdown)
/* Don't ask for POLLIN if we got a hangup. We won't receive more
* data anyway, but we will get POLLIN if SOCK_SHUTDOWN_EOF. */
if (!sock->hangup)
{
if (mask & AFD_POLL_READ)
ev |= POLLIN;
......@@ -1380,6 +1385,7 @@ static struct sock *create_socket(void)
sock->rd_shutdown = 0;
sock->wr_shutdown = 0;
sock->wr_shutdown_pending = 0;
sock->hangup = 0;
sock->nonblocking = 0;
sock->bound = 0;
sock->rcvbuf = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment