[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