mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-13 15:56:23 +01:00
Bug 324234 - Using g_io_add_watch_full() to wait for connect() to return
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. svn path=/trunk/; revision=7372
This commit is contained in:
parent
fcac96ed02
commit
f7f48d5c08
25
ChangeLog
25
ChangeLog
@ -1,3 +1,28 @@
|
||||
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
|
||||
|
@ -29,6 +29,44 @@
|
||||
* 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"
|
||||
@ -116,6 +154,7 @@ struct _GIOWin32Channel {
|
||||
int last_events;
|
||||
HANDLE event;
|
||||
gboolean write_would_have_blocked;
|
||||
gboolean ever_writable;
|
||||
};
|
||||
|
||||
#define LOCK(mutex) EnterCriticalSection (&mutex)
|
||||
@ -242,6 +281,7 @@ g_io_channel_win32_init (GIOWin32Channel *channel)
|
||||
channel->last_events = 0;
|
||||
channel->event = NULL;
|
||||
channel->write_would_have_blocked = FALSE;
|
||||
channel->ever_writable = FALSE;
|
||||
InitializeCriticalSection (&channel->mutex);
|
||||
}
|
||||
|
||||
@ -734,7 +774,9 @@ g_io_win32_prepare (GSource *source,
|
||||
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);
|
||||
@ -845,11 +887,15 @@ g_io_win32_check (GSource *source)
|
||||
(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
|
||||
@ -869,10 +915,12 @@ g_io_win32_check (GSource *source)
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
Loading…
Reference in New Issue
Block a user