pthread problem w/ GtkGLext
- From: Ray Clouse <ray clouse boeing com>
- To: gtk-list gnome org
- Cc: "Jones, Heiko" <heiko jones boeing com>
- Subject: pthread problem w/ GtkGLext
- Date: Thu, 12 Feb 2004 13:20:12 -0800
I'm porting a pthreaded OpenGL application to GTK+ and have run into
problems getting the threading to work.
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;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]