I've written a simplified example of what I'm trying to do threadwise and it's core dumping on me. The program is supposed to let you open multiple windows in separate threads where a timer updates a label. It opens the first window but then core dumps.
Any and all help appreciated! :)
-- ------------------------------------------------------------------------ Ray Clouse STICS Lab ray.clouse AT boeing.com Don't fear the penguins. clouse AT rayclouse.org
#include /usr/include/make/commondefs CFLAGS = -g `pkg-config gtk+-2.0 --cflags --libs --libs gthread-2.0` \ -D_REENTRANT -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 LDFLAGS = -lpthread -lm includedir = /usr/include/gtk-2.0/gtk/ LDADD = `pkg-config gtk+-2.0 --libs` default: main main: Makefile main.c $(CC) $(CFLAGS) $(LDFLAGS) main.c \ -o main clean: rm *.o
#include <gtk/gtk.h> #include <gdk/gdk.h> #include <glib.h> #include <glib/gthread.h> #include <semaphore.h> #include <pthread.h> #include <errno.h> #include <signal.h> #ifndef HAVE_DEFINES # define HAVE_DEFINES # define MAX_WINDOWS 10 # define MAX_THREADS 10 #endif typedef struct { int counter; GtkWidget *label; } timeoutargs; typedef struct { int threadnum; GtkWidget *viewwindow; pthread_t pthread; pthread_mutex_t taskmutex; pthread_cond_t taskcond; } viewthreadargs; void on_quit_activate (GtkMenuItem *menuitem, gpointer user_data) { gtk_main_quit(); } void on_viewwindow_delete_event (GtkWidget *window, gpointer user_data) { gtk_widget_destroy(window); } void on_exit2_activate (GtkWidget *button, gpointer user_data) { GtkWidget *window = (GtkWidget *) user_data; gtk_widget_destroy(window); } gint counter_callback(gpointer *data) { printf("begin counter_callback\n"); timeoutargs *t1 = (timeoutargs *) data; printf("1\n"); char *s1; t1->counter++; printf("2\n"); sprintf(s1, "%d", t1->counter); printf("3\n"); gdk_threads_enter(); printf("4\n"); gtk_label_set_text(GTK_LABEL(t1->label), s1); printf("5\n"); gdk_threads_leave(); printf("end counter_callback\n"); } GtkWidget* create_viewwindow (void) { GtkWidget *viewwindow; GtkWidget *vbox4; GtkWidget *menubar3; GtkWidget *menuitem9; GtkWidget *menuitem9_menu; GtkWidget *separatormenuitem3; GtkWidget *exit2; GtkAccelGroup *accel_group; timeoutargs *targ; printf("begin create_viewwindow\n"); accel_group = gtk_accel_group_new (); viewwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (viewwindow), ("Thread Test View")); vbox4 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox4); gtk_container_add (GTK_CONTAINER (viewwindow), vbox4); menubar3 = gtk_menu_bar_new (); gtk_widget_show (menubar3); gtk_box_pack_start (GTK_BOX (vbox4), menubar3, FALSE, FALSE, 0); menuitem9 = gtk_menu_item_new_with_mnemonic ("_File"); gtk_widget_show (menuitem9); gtk_container_add (GTK_CONTAINER (menubar3), menuitem9); menuitem9_menu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem9), menuitem9_menu); separatormenuitem3 = gtk_menu_item_new (); gtk_widget_show (separatormenuitem3); gtk_container_add (GTK_CONTAINER (menuitem9_menu), separatormenuitem3); gtk_widget_set_sensitive (separatormenuitem3, FALSE); exit2 = gtk_menu_item_new_with_mnemonic ("E_xit"); gtk_widget_show (exit2); gtk_container_add (GTK_CONTAINER (menuitem9_menu), exit2); g_signal_connect ((gpointer) viewwindow, "delete_event", G_CALLBACK (on_viewwindow_delete_event), NULL); g_signal_connect ((gpointer) exit2, "activate", G_CALLBACK (on_exit2_activate), viewwindow); if ((targ = (timeoutargs *) calloc(1, sizeof(timeoutargs))) == NULL) { printf("Cannot calloc timeout arg data.\n"); return NULL; } targ->label = gtk_label_new ("0"); targ->counter = 0; gtk_box_pack_start (GTK_BOX (vbox4), targ->label, TRUE, TRUE, 0); gtk_widget_show(targ->label); g_timeout_add((guint32) 1000, (GtkFunction) counter_callback, (gpointer) targ); gtk_window_add_accel_group (GTK_WINDOW (viewwindow), accel_group); printf("end create_viewwindow\n"); return viewwindow; } int create_view_wrapper(viewthreadargs *vtargs) { printf("begin create_view_wrapper\n"); gdk_threads_enter(); vtargs->viewwindow = create_viewwindow(); gtk_container_set_reallocate_redraws(GTK_CONTAINER(vtargs->viewwindow), TRUE); gtk_widget_show(vtargs->viewwindow); gdk_flush(); gdk_threads_leave(); printf("end create_view_wrapper\n"); } int on_create_view_activate (GtkMenuItem *menuitem, gpointer user_data) { pthread_t t1; struct sched_param param1; viewthreadargs *vtargs; GError *error = NULL; printf("begin on_create_view_activate\n"); if ((vtargs = (viewthreadargs *) calloc(1, sizeof(viewthreadargs))) == NULL) { printf(" on_create_view_activate: Cannot calloc view window thread info.\n"); return -1; } if ((pthread_create(&t1, NULL, (void *) create_view_wrapper, vtargs)) != 0) { printf(" Problem pthread_create\n"); return -1; } printf("end on_create_view_activate\n"); return 1; } GtkWidget* create_mainwindow (void) { GtkWidget *mainwindow; GtkWidget *vbox1; GtkWidget *menubar1; GtkWidget *menuitem1; GtkWidget *menuitem1_menu; GtkWidget *separatormenuitem1; GtkWidget *quit1; GtkWidget *create_view1; GtkWidget *label1; GtkAccelGroup *accel_group; accel_group = gtk_accel_group_new (); mainwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (mainwindow), "Thread Test"); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (mainwindow), vbox1); menubar1 = gtk_menu_bar_new (); gtk_widget_show (menubar1); gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0); menuitem1 = gtk_menu_item_new_with_mnemonic ("_File"); gtk_widget_show (menuitem1); gtk_container_add (GTK_CONTAINER (menubar1), menuitem1); menuitem1_menu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menuitem1_menu); separatormenuitem1 = gtk_menu_item_new (); gtk_widget_show (separatormenuitem1); gtk_container_add (GTK_CONTAINER (menuitem1_menu), separatormenuitem1); gtk_widget_set_sensitive (separatormenuitem1, FALSE); create_view1 = gtk_menu_item_new_with_mnemonic ("Create _View"); gtk_widget_show (create_view1); gtk_container_add (GTK_CONTAINER (menuitem1_menu), create_view1); quit1 = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group); gtk_widget_show (quit1); gtk_container_add (GTK_CONTAINER (menuitem1_menu), quit1); g_signal_connect ((gpointer) quit1, "activate", G_CALLBACK (on_quit_activate), NULL); g_signal_connect ((gpointer) create_view1, "activate", G_CALLBACK (on_create_view_activate), NULL); gtk_window_add_accel_group (GTK_WINDOW (mainwindow), accel_group); label1 = gtk_label_new("Main wind0w"); gtk_box_pack_start (GTK_BOX (vbox1), label1, FALSE, FALSE, 0); gtk_widget_show (label1); return mainwindow; } int main (int argc, char *argv[]) { GtkWidget *mainwindow; sigset_t sig_to_block; int i, j; /* init glib threads stuff for gtk */ g_thread_init(NULL); gdk_threads_init(); /* Setup the signals to block, threads will inherit this mask... */ sigemptyset(&sig_to_block); /* Block SIGPIPE so the write to sockets will not get us when socket closed */ sigaddset(&sig_to_block, SIGPIPE); /* Block SIG INT,TERM,SEGV so we can catch to close down and exit... */ sigaddset(&sig_to_block, SIGINT); sigaddset(&sig_to_block, SIGTERM); sigaddset(&sig_to_block, SIGSEGV); pthread_sigmask(SIG_BLOCK, &sig_to_block, NULL); gtk_set_locale (); gtk_init (&argc, &argv); mainwindow = create_mainwindow (); gtk_widget_show (mainwindow); gdk_threads_enter(); gtk_main (); gdk_threads_leave(); return 0; }