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

Reply via email to