Re: Win32 glib io problems
Tor Lillqvist <[email protected]>
| Newsgroups | gmane.comp.video.gimp.windows.devel,gmane.comp.gnome.gtk+.devel.general |
|---|---|
| Message-ID | <[email protected]> |
Thorsten Maerz wrote: > I assume you're talking about sockets. We had the same problems with > an email client (Sylphed-Claws) and patched some parts of glib: Herman Bloggs wrote: > Basically async socket communication is slow or times > out unless the mouse pointer is being moved around > within a gtk window. I think I found the cause for Herman's problem, hopefully it also helps in the Sylpheed-Claws case). It was in gmain.c as guessed, but the suggested fix (never using INFINITE timeout, but 10 milliseconds instead) was wrong. (Well, it might have worked as a workaround, but it was not fixing the actual cause of the bug.) The problem was that g_poll only waited for events for GPollFDs being watched for G_IO_IN. Herman's sample code (thanks!) watched a non-blocking socket in the process of being connect()ed. One watches for G_IO_OUT in this case. The select thread in giowin32.c did correctly call select() on the socket, and this select() returned when the connection succeeded, and the correct Windows event was fired. But, the main thread in g_poll never noticed, as it wasn't waiting for that event at all. 2002-10-27 Tor Lillqvist <[email protected]> * glib/gmain.c (g_poll): Fix for bug reported by Herman Bloggs (http://mail.gnome.org/archives/gtk-devel-list/2002-October/msg00101.html) and others. We waited for events only for GPollFDs whose events field had G_IO_IN set. We need to wait also for events for GPollFDs that have just G_IO_OUT set. Non-blocking sockets in the process of being connect()ed are one such case. Also silence a couple of gcc warnings. Index: glib/gmain.c =================================================================== RCS file: /cvs/gnome/glib/glib/gmain.c,v retrieving revision 1.83.2.3 retrieving revision 1.83.2.4 diff -u -2 -r1.83.2.3 -r1.83.2.4 --- glib/gmain.c 6 Aug 2002 14:58:21 -0000 1.83.2.3 +++ glib/gmain.c 26 Oct 2002 22:40:44 -0000 1.83.2.4 @@ -269,15 +269,12 @@ if (f->fd >= 0) { - if (f->events & G_IO_IN) + if (f->fd == G_WIN32_MSG_HANDLE) + poll_msgs = TRUE; + else { - if (f->fd == G_WIN32_MSG_HANDLE) - poll_msgs = TRUE; - else - { #ifdef G_MAIN_POLL_DEBUG - g_print ("g_poll: waiting for %#x\n", f->fd); + g_print ("g_poll: waiting for %#x\n", f->fd); #endif - handles[nhandles++] = (HANDLE) f->fd; - } + handles[nhandles++] = (HANDLE) f->fd; } } @@ -328,5 +325,8 @@ timer = SetTimer (NULL, 0, timeout, NULL); if (timer == 0) - g_warning (G_STRLOC ": SetTimer() failed"); + { + g_warning (G_STRLOC ": SetTimer() failed"); + ready = WAIT_TIMEOUT; + } else { @@ -382,5 +382,5 @@ #ifdef G_MAIN_POLL_DEBUG - g_print ("wait returns %d%s\n", + g_print ("wait returns %ld%s\n", ready, (ready == WAIT_FAILED ? " (WAIT_FAILED)" : @@ -409,8 +409,11 @@ for (f = fds; f < &fds[nfds]; ++f) { - if ((f->events & G_IO_IN) + if ((f->events & (G_IO_IN | G_IO_OUT)) && f->fd == (gint) handles[ready - WAIT_OBJECT_0]) { - f->revents |= G_IO_IN; + if (f->events & G_IO_IN) + f->revents |= G_IO_IN; + else + f->revents |= G_IO_OUT; #ifdef G_MAIN_POLL_DEBUG g_print ("g_poll: got event %#x\n", f->fd);