Attaching file in email body... At 02:36 AM 10/12/2006, Daniel Yek wrote: >Hi, > >I am attaching the source code of a small test program here. > >Could somebody enlighten me why after an I/O Channel operation >(g_io_channel_shutdown() here), the GTK+ program started to use up 100% CPU? > >Is it monitoring something? Do I need to undo g_io_add_watch() somehow? >What operation is needed to not get into such situation? > >Thanks.
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <gtk/gtk.h> char buf[] = "Line 1\nLine 2\nLine 3\nLine 4\n"; int mypipe[2]; GIOChannel *giochannel; void gio_shutdown(GIOChannel *giochannel) { GError *gerror = NULL; GIOStatus status; printf("Entering gio_shutdown\n"); // Shutdown I/O Channel would close the file descriptor, mypipe[0]! status = g_io_channel_shutdown(giochannel, FALSE, // Flush? &gerror); if (status != G_IO_STATUS_NORMAL) { fprintf(stderr, "ERROR shutting down I/O Channel\n"); } if (gerror) g_error_free(gerror); } static gboolean gio_channel_hup(GIOChannel *giochannel, GIOCondition giocondition, gpointer data) { printf("Received HUP. Shutting down I/O Channel.\n"); gio_shutdown(giochannel); return FALSE; } void read_io_channel(GIOChannel *giochannel) { gchar *str = NULL; gsize length = 0; GError *gerror = NULL; GIOStatus status; printf("Entering read_io_channel\n"); status = g_io_channel_read_line(giochannel, &str, &length, NULL, // terminator_pos &gerror); if (status != G_IO_STATUS_NORMAL) { fprintf(stderr, "ERROR reading I/O Channel\n"); } printf("str = %s\n", str); if (gerror) g_error_free(gerror); } // Type: GIOFunc // The function should return FALSE if the event source should be removed. static gboolean gio_channel_handler(GIOChannel *giochannel, GIOCondition giocondition, gpointer data) { fprintf(stderr, "gio_channel_handler().\n"); if (giocondition == G_IO_IN) { read_io_channel(giochannel); return TRUE; } else if (giocondition == G_IO_HUP) { gio_shutdown(giochannel); } return FALSE; } void dialog_handler(GtkDialog *dialog, gint response, gpointer data) { printf("Entering dialog_handler\n"); switch(response) { case GTK_RESPONSE_DELETE_EVENT: gtk_main_quit(); break; // Close write-end of the pipe and then write to it causes CPU to max-up. case GTK_RESPONSE_APPLY: // write fprintf(stderr, "Writing!\n"); if (-1 == write(mypipe[1], buf, sizeof(buf))) { fprintf(stderr, "ERROR writing to pipe.\n"); } printf("Succeeded writing to pipe!\n"); break; case GTK_RESPONSE_YES: // read fprintf(stderr, "Reading...\n"); read_io_channel(giochannel); break; case GTK_RESPONSE_CANCEL: // Close write-end fprintf(stderr, "Closing the write-end...\n"); close(mypipe[1]); break; case GTK_RESPONSE_NO: // Close read-end of the pipe fprintf(stderr, "Closing the read-end...\n"); close(mypipe[0]); break; case GTK_RESPONSE_HELP: // Shutdown I/O channels fprintf(stderr, "Shutting down I/O channels...\n"); gio_shutdown(giochannel); break; default: printf("ERROR: Unknown response: %x\n", response); break; } return; } GtkDialog * create_user_interface() { GtkDialog *dialog; dialog = GTK_DIALOG( gtk_dialog_new_with_buttons("iochannel Test!", // Title NULL, // Parent 0, // GtkDialogFlags // It is OK to have only GTK_RESPONSE_*, // without the label below! "_write", GTK_RESPONSE_APPLY, "_read", GTK_RESPONSE_YES, "_closeWrite", GTK_RESPONSE_CANCEL, "c_loseRead", GTK_RESPONSE_NO, "_shutdownIOChannel", GTK_RESPONSE_HELP, NULL)); // Must be NULL-terminated! gtk_dialog_set_default_response(dialog, GTK_RESPONSE_CLOSE); g_signal_connect(dialog, "response", G_CALLBACK(dialog_handler), /*userdata*/ NULL); gtk_widget_show_all(GTK_WIDGET(dialog)); return dialog; } int main(int argc, char **argv) { GtkDialog *dialog; gtk_init(&argc, &argv); if (-1 == pipe(mypipe)) { fprintf(stderr, "ERROR creating pipe\n"); exit(1); } giochannel = g_io_channel_unix_new(mypipe[0]); g_io_add_watch(giochannel, G_IO_IN|G_IO_HUP, gio_channel_handler, /*userdata*/ NULL); //g_io_add_watch(giochannel, G_IO_HUP, gio_channel_hup, /*userdata*/ NULL); dialog = create_user_interface(); // gtk_dialog_run() will dismiss after get one result. // printf("Running dialog box\n"); // gtk_dialog_run(dialog); printf("Entering gtk_main\n"); gtk_main(); g_free(dialog); return 0; } -- Daniel Yek _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list