fix for ice related stuff



hackers,

so when the logout dialog is up, gnome-session will start using 100% of
the CPU.  i've tracked it down and this patch fixes it for me.

i'm also attaching 2 small programs which will exhibit the problem.

owen, havoc: does this patch look correct?

jacob
-- 
"don't get me wrong, i think that radiohead are amazing. i love their
 music and i love their ethos, but that thom yorke guy always seems to
 be complaining." -- moby
Index: gnome-ice.c
===================================================================
RCS file: /cvs/gnome/libgnomeui/libgnomeui/gnome-ice.c,v
retrieving revision 1.13
diff -u -r1.13 gnome-ice.c
--- gnome-ice.c	21 Feb 2002 21:57:01 -0000	1.13
+++ gnome-ice.c	24 Apr 2002 05:03:43 -0000
@@ -45,14 +45,26 @@
 static void new_ice_connection (IceConn connection, IcePointer client_data,
 				Bool opening, IcePointer *watch_data);
 
+typedef struct {
+  GIOChannel *channel;
+  IceConn     connection;
+  guint       input_id;
+} ConnectionData;
+
+static void add_watch (ConnectionData *cdata);
+
 /* This is called when data is available on an ICE connection.  */
 static gboolean
 process_ice_messages (GIOChannel   *source,
 		      GIOCondition  condition,
 		      gpointer      data)
 {
-  IceConn connection = (IceConn) data;
+  ConnectionData *cdata = data;
+  IceConn connection = cdata->connection;
   IceProcessMessagesStatus status;
+  gboolean add_the_watch = TRUE;
+
+  g_source_remove (cdata->input_id);
 
   status = IceProcessMessages (connection, NULL, NULL);
 
@@ -71,10 +83,24 @@
 	{
 	  IceSetShutdownNegotiation (connection, False);
 	  IceCloseConnection (connection);
+	  cdata->input_id = 0;
+	  add_the_watch = FALSE;
 	}
     }
 
-  return TRUE;
+  if (add_the_watch)
+    add_watch (cdata);
+
+  return add_the_watch;
+}
+
+static void
+add_watch (ConnectionData *cdata)
+{
+  cdata->input_id = g_io_add_watch (cdata->channel,
+				    G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
+				    process_ice_messages,
+				    cdata);
 }
 
 /* This is called when a new ICE connection is made.  It arranges for
@@ -83,30 +109,30 @@
 new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
 		    IcePointer *watch_data)
 {
-  guint input_id;
+  ConnectionData *cdata;  
 
   if (opening)
     {
-      GIOChannel *channel;
       /* Make sure we don't pass on these file descriptors to any
          exec'ed children */
       fcntl(IceConnectionNumber(connection),F_SETFD,
 	    fcntl(IceConnectionNumber(connection),F_GETFD,0) | FD_CLOEXEC);
 
-      channel = g_io_channel_unix_new (IceConnectionNumber (connection));
-      input_id = g_io_add_watch (channel,
-				 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
-				 process_ice_messages,
-				 connection);
-      g_io_channel_unref (channel);
+      cdata = g_new (ConnectionData, 1);
+      cdata->connection = connection;
+      cdata->channel = g_io_channel_unix_new (IceConnectionNumber (connection));
+      add_watch (cdata);
 
-      *watch_data = (IcePointer) GUINT_TO_POINTER (input_id);
+      *watch_data = cdata;
     }
   else
     {
-      input_id = GPOINTER_TO_UINT ((gpointer) *watch_data);
+      cdata = *watch_data;
 
-      g_source_remove (input_id);
+      if (cdata->input_id)
+	g_source_remove (cdata->input_id);
+      g_io_channel_unref (cdata->channel);
+      g_free (cdata);
     }
 }
 
#include <gtk/gtk.h>

static gboolean
io_cb (GIOChannel *ioc, GIOCondition cond, gpointer null)
{
	GtkWidget *d;

	d = gtk_message_dialog_new (NULL,
				    0,
				    GTK_MESSAGE_INFO,
				    GTK_BUTTONS_OK,
				    "THis is a test~!");
	gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_OK);
	gtk_dialog_run (GTK_DIALOG (d));
	gtk_widget_destroy (d);

	return TRUE;
}

int
main (int argc, char *argv[])
{
	GIOChannel *ioc;

	gtk_init (&argc, &argv);

	ioc = g_io_channel_unix_new (0);
	g_io_add_watch (ioc, G_IO_IN, io_cb, NULL);
	g_io_channel_unref (ioc);

	gtk_main ();

	return 0;
}
#include <gtk/gtk.h>

static GIOChannel *ioc;
static guint source;

static void create_source (void);

static gboolean
io_cb (GIOChannel *ioc, GIOCondition cond, gpointer null)
{
	GtkWidget *d;

	g_source_remove (source);

	d = gtk_message_dialog_new (NULL,
				    0,
				    GTK_MESSAGE_INFO,
				    GTK_BUTTONS_OK,
				    "THis is a test~!");
	gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_OK);
	gtk_dialog_run (GTK_DIALOG (d));
	gtk_widget_destroy (d);

	create_source ();

	return TRUE;
}

static void
create_source (void)
{
	source = g_io_add_watch (ioc, G_IO_IN, io_cb, NULL);
}

int
main (int argc, char *argv[])
{
	gtk_init (&argc, &argv);

	ioc = g_io_channel_unix_new (0);
	create_source ();

	gtk_main ();

	return 0;
}


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