Re: timeout function not called



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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]