socket/win32: flush pending read before signaling HUP

Unix and Windows gio GSocket behaves differently when the socket is
closed by the peer. On Unix, the client receives pending data before
receiving HUP. But on Windows, the HUP may come before, resulting in
unreliable and racy code. We should have same behaviour on all
platforms.

According to MSDN documentation: "an application should check for
remaining data upon receipt of FD_CLOSE to avoid any possibility of
losing data."

https://bugzilla.gnome.org/show_bug.cgi?id=669810
This commit is contained in:
Marc-André Lureau 2012-02-10 02:02:29 +01:00
parent 6ca817c3f2
commit 704a2ca02d

View File

@ -3040,8 +3040,26 @@ update_condition (GSocket *socket)
if (socket->priv->current_events & (FD_READ | FD_ACCEPT))
condition |= G_IO_IN;
if (socket->priv->current_events & FD_CLOSE ||
socket->priv->closed)
if (socket->priv->current_events & FD_CLOSE)
{
int r, errsv, buffer;
r = recv (socket->priv->fd, &buffer, sizeof (buffer), MSG_PEEK);
if (r < 0)
errsv = get_socket_errno ();
if (r > 0 ||
(r < 0 && errsv == WSAENOTCONN))
condition |= G_IO_IN;
else if (r == 0 ||
(r < 0 && (errsv == WSAESHUTDOWN || errsv == WSAECONNRESET ||
errsv == WSAECONNABORTED || errsv == WSAENETRESET)))
condition |= G_IO_HUP;
else
condition |= G_IO_ERR;
}
if (socket->priv->closed)
condition |= G_IO_HUP;
/* Never report both G_IO_OUT and HUP, these are