+2008-08-20 Tor Lillqvist <tml@novell.com>
+
+ Bug 324234 - Using g_io_add_watch_full() to wait for connect() to
+ return on a non-blocking socket returns prematurely
+
+ Bug 548278 - Async GETs connections are always terminated
+ unexpectedly on Windows
+
+ * glib/giowin32.c: Add one more state variable to the
+ GIOWin32Channel struct, ever_writable. Initialise it to FALSE, set
+ to TRUE when the WSAEventSelect() indicates FD_WRITE, and never
+ reset to FALSE.
+
+ Don't do the WSASetEvent() in g_io_win32_prepare() unless
+ ever_writable is TRUE. Don't automatically indicate G_IO_OUT in
+ g_io_win32_check() unless ever_writable is TRUE.
+
+ This fixes the behaviour of the test case program in bug #548278,
+ and the "Testcase for the spurious OUT event bug" in bug
+ #324234. It also doesn't seem to break anything. Not that there is
+ any exhaustive test suite...
+
+ Add a comment with a list of bugs that are related to the code in
+ this file.
+
2008-08-18 Matthias Clasen <mclasen@redhat.com>
* configure.in: Bump version
* GLib at ftp://ftp.gtk.org/pub/gtk/.
*/
+/*
+ * Bugs that are related to the code in this file:
+ *
+ * Bug 137968 - Sometimes a GIOFunc on Win32 is called with zero condition
+ * http://bugzilla.gnome.org/show_bug.cgi?id=137968
+ *
+ * Bug 324234 - Using g_io_add_watch_full() to wait for connect() to return on a non-blocking socket returns prematurely
+ * http://bugzilla.gnome.org/show_bug.cgi?id=324234
+ *
+ * Bug 331214 - g_io_channel async socket io stalls
+ * http://bugzilla.gnome.org/show_bug.cgi?id=331214
+ *
+ * Bug 338943 - Multiple watches on the same socket
+ * http://bugzilla.gnome.org/show_bug.cgi?id=338943
+ *
+ * Bug 357674 - 2 serious bugs in giowin32.c making glib iochannels useless
+ * http://bugzilla.gnome.org/show_bug.cgi?id=357674
+ *
+ * Bug 425156 - GIOChannel deadlocks on a win32 socket
+ * http://bugzilla.gnome.org/show_bug.cgi?id=425156
+ *
+ * Bug 468910 - giofunc condition=0
+ * http://bugzilla.gnome.org/show_bug.cgi?id=468910
+ *
+ * Bug 500246 - Bug fixes for giowin32
+ * http://bugzilla.gnome.org/show_bug.cgi?id=500246
+ *
+ * Bug 548278 - Async GETs connections are always terminated unexpectedly on windows
+ * http://bugzilla.gnome.org/show_bug.cgi?id=548278
+ *
+ * Bug 548536 - giowin32 problem when adding and removing watches
+ * http://bugzilla.gnome.org/show_bug.cgi?id=548536
+ *
+ * When fixing bugs related to the code in this file, either the above
+ * bugs or others, make sure that the test programs attached to the
+ * above bugs continue to work.
+ */
+
#include "config.h"
#include "glib.h"
int last_events;
HANDLE event;
gboolean write_would_have_blocked;
+ gboolean ever_writable;
};
#define LOCK(mutex) EnterCriticalSection (&mutex)
channel->last_events = 0;
channel->event = NULL;
channel->write_would_have_blocked = FALSE;
+ channel->ever_writable = FALSE;
InitializeCriticalSection (&channel->mutex);
}
g_print ("\n setting last_events=0");
channel->last_events = 0;
- if ((event_mask & FD_WRITE) && !channel->write_would_have_blocked)
+ if ((event_mask & FD_WRITE) &&
+ channel->ever_writable &&
+ !channel->write_would_have_blocked)
{
if (channel->debug)
g_print (" WSASetEvent(%p)", (WSAEVENT) watch->pollfd.fd);
(HANDLE) watch->pollfd.fd);
ResetEvent ((HANDLE) watch->pollfd.fd);
}
+ else if (events.lNetworkEvents & FD_WRITE)
+ channel->ever_writable = TRUE;
channel->last_events = events.lNetworkEvents;
}
+
watch->pollfd.revents = 0;
if (channel->last_events & (FD_READ | FD_ACCEPT))
watch->pollfd.revents |= G_IO_IN;
+
if (channel->last_events & FD_WRITE)
watch->pollfd.revents |= G_IO_OUT;
else
}
/* 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.
+ * writability, and if we have ever got a FD_WRITE event, and
+ * 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->ever_writable &&
!channel->write_would_have_blocked &&
(channel->event_mask & FD_WRITE))
watch->pollfd.revents |= G_IO_OUT;