Re: What causes GLib I/O Channels operations to use up 100% CPU in GTK+ app.?
- From: Daniel Yek <dyek real com>
- To: gtk-app-devel-list gnome org
- Subject: Re: What causes GLib I/O Channels operations to use up 100% CPU in GTK+ app.?
- Date: Thu, 12 Oct 2006 02:41:06 -0700
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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]