[prev in list] [next in list] [prev in thread] [next in thread]
List: gtk-app-devel
Subject: Re: timeout function not called
From: James Scott Jr <skoona () verizon ! net>
Date: 2007-10-05 23:28:28
Message-ID: 1191626908.26424.2.camel () homedev ! skoona ! net
[Download RAW message or body]
Vicki,
Here is a more complete example of how to resolve your issue.
Compile with this command
'# gcc -Wall -g -O2 `pkg-config --libs --cflags gtk+-2.0 glib-2.0
gthread-2.0` gprogress.c'
BEGIN-CODE
#include <gtk/gtk.h>
/* no globals */
typedef struct _INSTANCE_VALUES
{
GtkWidget *progressbar;
GThread *tid_growPart;
gboolean b_pulse_control;
gint i_growPart_rc;
} STEMP, *PST;
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#define EXIT_SUCESS 0
#endif
static gpointer fn_growPart (PST pInstance);
static gboolean fn_progress_update (PST pInstance);
static void cb_push_button_clicked (GtkButton *button, PST pInstance);
int main (int argc, char *argv[]);
int main (int argc, char *argv[])
{
GtkWidget *window = NULL;
GtkWidget *widget = NULL;
GtkWidget *box = NULL;
PST pInstance = NULL;
g_thread_init (NULL);
gdk_threads_init ();
gtk_init (&argc, &argv);
pInstance = g_new0 (STEMP, 1);
g_return_val_if_fail (pInstance != NULL, -1);
/* create app window */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete-event", gtk_main_quit, NULL);
gtk_window_set_title (GTK_WINDOW (window), "GrowPart Thread Example");
box = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER(window), box);
pInstance->progressbar = gtk_progress_bar_new ();
gtk_progress_bar_set_text (GTK_PROGRESS_BAR(pInstance->progressbar),
"Not Running!");
gtk_box_pack_start (GTK_BOX(box), pInstance->progressbar, TRUE, TRUE,
0);
widget = gtk_button_new_from_stock (GTK_STOCK_APPLY);
g_signal_connect (G_OBJECT(widget), "clicked",
G_CALLBACK(cb_push_button_clicked), pInstance);
gtk_box_pack_end (GTK_BOX(box), widget, TRUE, TRUE, 0);
gtk_widget_show_all (GTK_WIDGET(window));
/*
* enter the GTK main loop
*/
gdk_threads_enter ();
gtk_main ();
gdk_threads_leave ();
g_free (pInstance);
return 0;
}
static void cb_push_button_clicked (GtkButton *button, PST pInstance)
{
g_return_if_fail (pInstance != NULL);
pInstance->b_pulse_control = TRUE;
gtk_progress_bar_set_text (GTK_PROGRESS_BAR(pInstance->progressbar),
"Please Wait!");
g_timeout_add(100, (GSourceFunc)fn_progress_update, pInstance);
pInstance->tid_growPart = g_thread_create ( (GThreadFunc)fn_growPart,
pInstance, TRUE, NULL);
}
static gboolean fn_progress_update (PST pInstance)
{
g_return_val_if_fail (pInstance != NULL, FALSE);
if (pInstance->b_pulse_control)
{
gtk_progress_bar_pulse
(GTK_PROGRESS_BAR(pInstance->progressbar));
return TRUE;
} else {
pInstance->i_growPart_rc = GPOINTER_TO_INT( g_thread_join
(pInstance->tid_growPart) );
gtk_progress_bar_set_text
(GTK_PROGRESS_BAR(pInstance->progressbar), "Not Running!");
gtk_progress_bar_set_fraction
(GTK_PROGRESS_BAR(pInstance->progressbar),0.0);
return FALSE;
}
}
/*
* gthread routine
* -- never do any gtk calls from this thread - NEVER
*/
static gpointer fn_growPart (PST pInstance)
{
gint i_index = 0;
if (pInstance == NULL) {
g_thread_exit( GINT_TO_POINTER(EXIT_FAILURE) );
}
/* do work */
/* growPart(); */
while (i_index++ < 40) {
g_usleep (250000); /* 1/4 second * 40 = 10 seconds */
}
pInstance->b_pulse_control = FALSE;
g_thread_exit( GINT_TO_POINTER( EXIT_SUCESS ) );
return NULL;
}
END-CODE
James,
On Thu, 2007-10-04 at 13:27 -0700, v_wishful@sandiego.com wrote:
> Thanks James for giving me my first experience with Thread programming!
> I tried the code you sent me, but unfortunately, I still can't get the
> progress_update
> function to run, looks like it never gets called. Any idea why this
> might be happening?
> growPart still runs.
>
> Thanks,
>
> Vicki
>
>
> [Hide Quoted Text]
> GTK program before. The ret=wait(null) causes execution to stop at that
>
> point and wait for growPart() to finish. A way to get around the
> logistics of fork() is to use threads directly. Consider the following;
>
> /* globals */
> gboolean b_pulse_control = FALSE
> GThread *grow_thread_id = NULL;
> gint global_ret = 0;
>
>
> b_pulse_control = TRUE;
> timer = g_timeout_add(50, (GSourceFunc) progress_update,
> (gpointer)progressbar);
>
> grow_thread_id = g_thread_create ( growPart_thread, &b_pulse_control,
> TRUE, NULL);
>
>
> static gboolean progress_update (gpointer progressbar)
> {
> if (b_pulse_control)
> {
> gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressbar));
> return true;
> } else {
> global_ret = GPOINTER_TO_INT( g_thread_join (grow_thread) );
> return FALSE;
> }
>
> }
>
> static gpointer growPart_thread(gpointer b_pulse)
> {
>
> /* do work */
> growPart();
>
> *b_pulse = FALSE;
> g_thread_exit( GINT_TO_POINTER( 1 ) );
>
> }
>
> I would do the passing of control values via a structure to avoid the
> use of globals,
> but this should work for you.
>
>
> ------------------------------------------
> Invent your own San Diego at sandiego.com!
>
>
> _______________________________________________
> gtk-app-devel-list mailing list
> gtk-app-devel-list@gnome.org
> http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic