I am developping a program in C that uses GTK+3 and follows - more or less - the MVC architecture:
- The model is updated each 20 ms by calling model_update (it does not call to GTK functions) ;
- The GUI is updated by calling gui_update each 50 ms by reading model variables.
My problem is that the GUI freezes after a random running time, it can be 20 minutes or more than 1 hour and I do not know why. Maybe there is something I should know about GTK ?
Note : Access to model variables is protected by using mutex.
Thanks a lot for your help !!
#include <signal.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/prctl.h>
void *
thread_gui(void* data)
{
g_timeout_add(50, handler_timer_gui_update, NULL); // updates the GUI each 50ms
gtk_main();
pthread_exit(NULL);
}
gint
handler_timer_gui_update(gpointer data)
{
gui_update();
// gui_update reads the model and updates GUI by using
// gtk_label_set_text, gtk_spin_button_set_value, cairo_paint
return TRUE;
}
void
launch_periodical_call_updating_model( )
{
signal( SIGRTMIN + 1, model_update );
timer_t timer;
struct sigevent event;
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = SIGRTMIN + 1;
event.sigev_value.sival_ptr = &timer;
timer_create(CLOCK_REALTIME, &event, &timer);
struct itimerspec spec;
spec.it_value.tv_nsec = 20 * 1000000; // updates the model each 20 ms
spec.it_value.tv_sec = 0;
spec.it_interval = spec.it_value;
timer_settime( timerModel, 0, &spec, NULL);
}
int
main( int argc, char *argv[] )
{
pthread_t pthread_gui;
init_model( ); // init model variables
launch_periodical_call_updating_model( );
// signal capture to exit
signal( SIGINT, ctrlc_handler );
signal( SIGTERM, ctrlc_handler );
// GUI
g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
gtk_init( &argc, &argv );
create_gui ( ); // building GTK Window with widgets
pthread_create(&pthread_gui, NULL, thread_gui, NULL);
gdk_threads_leave();
// Leaving the program
pthread_join( pthread_gui, NULL );
stop_model( ); //It stops to update the model and releases memory
return 0;
}
void
ctrlc_handler( int sig )
{
gtk_main_quit();
}