Re: Win32 glib io problems



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  <tml iki fi>

	* 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);





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]