When WSAEnumNetworkEvents() signals FD_CONNECT that means that the

2007-07-06  Tor Lillqvist  <tml@novell.com>

	* glib/giowin32.c (g_io_win32_check): When WSAEnumNetworkEvents()
	signals FD_CONNECT that means that the connection attempt
	finished, either successfully or failed. Test explicitly whether
	the connnection succeeded and set either G_IO_OUT if it did,
	G_IO_ERR|G_IO_HUP if it failed.

	Make sure we never set both G_IO_OUT and G_IO_HUP simultaneously
	because in Unix poll(2) POLLOUT and POLLHUP are mutually
	exclusive.

	Ignore whether the caller wants to watch G_IO_HUP or not. Always
	select for FD_CLOSE because Unix poll(2) also ignores whether
	POLLHUP in set the requested events bitmask or not.


svn path=/trunk/; revision=5600
This commit is contained in:
Tor Lillqvist 2007-07-06 01:22:53 +00:00 committed by Tor Lillqvist
parent 36dab3af81
commit 09d6197943
2 changed files with 41 additions and 7 deletions

View File

@ -1,3 +1,19 @@
2007-07-06 Tor Lillqvist <tml@novell.com>
* glib/giowin32.c (g_io_win32_check): When WSAEnumNetworkEvents()
signals FD_CONNECT that means that the connection attempt
finished, either successfully or failed. Test explicitly whether
the connnection succeeded and set either G_IO_OUT if it did,
G_IO_ERR|G_IO_HUP if it failed.
Make sure we never set both G_IO_OUT and G_IO_HUP simultaneously
because in Unix poll(2) POLLOUT and POLLHUP are mutually
exclusive.
Ignore whether the caller wants to watch G_IO_HUP or not. Always
select for FD_CLOSE because Unix poll(2) also ignores whether
POLLHUP in set the requested events bitmask or not.
Fri Jun 29 2007 Matthias Clasen <mclasen@redhat.com>
* configure.in: Bump version

View File

@ -822,8 +822,7 @@ g_io_win32_prepare (GSource *source,
event_mask |= (FD_READ | FD_ACCEPT);
if (watch->condition & G_IO_OUT)
event_mask |= (FD_WRITE | FD_CONNECT);
if (watch->condition & G_IO_HUP)
event_mask |= FD_CLOSE;
event_mask |= FD_CLOSE;
if (channel->event_mask != event_mask /* || channel->event != watch->pollfd.fd*/)
{
@ -936,13 +935,32 @@ g_io_win32_check (GSource *source)
watch->pollfd.revents = 0;
if (channel->last_events & (FD_READ | FD_ACCEPT))
watch->pollfd.revents |= G_IO_IN;
if (channel->last_events & (FD_WRITE | FD_CONNECT))
if (channel->last_events & FD_WRITE)
watch->pollfd.revents |= G_IO_OUT;
if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE)))
watch->pollfd.revents |= G_IO_HUP;
else
{
/* We have called WSAEnumNetworkEvents() above but it didn't
* set FD_WRITE.
*/
if (events.lNetworkEvents & FD_CONNECT)
{
if (events.iErrorCode[FD_CONNECT_BIT] == 0)
watch->pollfd.revents |= G_IO_OUT;
else
watch->pollfd.revents |= (G_IO_HUP | G_IO_ERR);
}
if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE)))
watch->pollfd.revents |= G_IO_HUP;
}
if (!channel->write_would_have_blocked && (channel->event_mask & FD_WRITE))
watch->pollfd.revents |= G_IO_OUT; /* This sucks but... */
/* Regardless of WSAEnumNetworkEvents() result, if watching for
* writability, unless last write would have blocked set
* G_IO_OUT. But never set both G_IO_OUT and G_IO_HUP.
*/
if (!(watch->pollfd.revents & G_IO_HUP) &&
!channel->write_would_have_blocked &&
(channel->event_mask & FD_WRITE))
watch->pollfd.revents |= G_IO_OUT;
return ((watch->pollfd.revents | buffer_condition) & watch->condition);