On Mon, 2006-02-06 at 11:22, Michael Torrie wrote:

> I have attached a sample file that uses threads in the way you described 
> in your last post.

I generally like to make code examples compile without warning. Did you
even try to compile this?

________________________________________________________________________
> #include <stdio.h>
> #include <stdlib.h>
> #include <gtk/gtk.h>
> #include <glib.h>
> #include <pthread.h>

#include <unistd.h> /* sleep() - on Unix, anyway */

> gint thread_count=0;
> gint dead_threads;
> 
> GSList *threads;
> 
> struct thread_info_data {
>       GtkTextBuffer *buffer;
>       gint id;
>       pthread_t tid;
>       gint terminate;
> };
> 
> void thread (void *data) {

void * thread(void *data) {

>       struct thread_info_data *info;
>       GtkTextIter iter;
>       GString *message;
> 
> 
>       info=(struct thread_info_data *)data;
>       message=g_string_new("");
> 
>       while(info->terminate == 0 ) {
>               sleep(1);
>               g_string_printf(message,"Thread %d here.\n",info->id);
>               g_print("%s",message->str);
>               
>               gdk_threads_enter();
>               gtk_text_buffer_get_end_iter(info->buffer,&iter);
>               gtk_text_buffer_insert(info->buffer,&iter,message->str,-1);
>               gdk_threads_leave();
>       }
>       g_print("Thread %d stopping.\n",info->id);
>       gdk_threads_enter(); //borrowing a lock from gtk to lock our variable
>       dead_threads++;
>       gdk_threads_leave(); //we could and should use a counting semaphore
>       g_string_free(message,NULL);

        g_string_free(message,FALSE); /* Hope NULL means FALSE here */
        return 0;
> }
> 
> void stop_thread(gpointer data, gpointer user_data) {
>       struct thread_info_data *thread;
> 
>       thread=data;
>       thread->terminate=1;
>       g_print("Asked thread %d to stop.\n",thread->id);
>       
>       //here we ought to make sure the thread really has died
> //    pthread_join(thread->tid,NULL);
> }
> 
> void on_destroy(GtkWidget *widget, gpointer data) {
>       g_slist_foreach(threads,stop_thread,NULL);
> 
>       while(dead_threads < thread_count) {
>               while(gtk_events_pending()) {
>                       gtk_main_iteration();
>               }
>               sleep(0);
>       }
>       gtk_main_quit();
> }
> 
> void on_button_clicked(GtkWidget *widget, gpointer data) {
>       GtkTextBuffer *buffer;
>       GtkTextIter iter;
>       struct thread_info_data *thread_info;
>       
>       buffer=GTK_TEXT_BUFFER(data);
> 
>       thread_info=g_malloc(sizeof(struct thread_info_data));
>       thread_info->buffer=buffer;
>       thread_info->id=thread_count++;
>       thread_info->terminate=0;
> 
>       threads=g_slist_append(threads,thread_info);
> 
>       pthread_create(&(thread_info->tid),NULL,thread,thread_info);
>       
> 
>       gtk_text_buffer_get_end_iter(buffer,&iter);
>       gtk_text_buffer_insert(buffer,&iter,"Button clicked!\n",-1);
>       g_print("Button clicked.\n");
> 
> 
> }
> 
> 
> int main(int argc, char *argv[]) {
>       GtkWidget *window;
>       GtkWidget *button;
>       GtkWidget *vbox;
>       GtkWidget *viewarea;
>       GtkWidget *view;
>       GtkWidget *buffer;

        GtkTextBuffer *buffer; /* GtkTextBuffer doesn't inherit from GtkWidget!
*/

>       threads=NULL;
> 
> 
>       g_thread_init (NULL);
>       gdk_threads_init ();
> 
>       gtk_init(&argc, &argv);
> 
>       window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
> 
>       gtk_signal_connect(GTK_OBJECT(window),"destroy",
>                          GTK_SIGNAL_FUNC(on_destroy),NULL);
>       gtk_container_set_border_width(GTK_CONTAINER(window),10);
> 
>       vbox=gtk_vbox_new(FALSE,5);
>       gtk_container_add(GTK_CONTAINER(window),vbox);
>       gtk_widget_show(vbox);
> 
>       viewarea=gtk_scrolled_window_new(NULL,NULL);
>       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(viewarea),
>                                      GTK_POLICY_AUTOMATIC,
>                                      GTK_POLICY_AUTOMATIC);
>       gtk_box_pack_start(GTK_BOX(vbox),viewarea,TRUE,TRUE,2);
>       gtk_widget_show(viewarea);
>       
>       view=gtk_text_view_new();
> 
>       buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
> 
>       gtk_text_buffer_set_text(buffer,"The threads will write here.\n",-1);
>       gtk_container_add(GTK_CONTAINER(viewarea),view);
>       gtk_widget_show(view);
>       
>       button=gtk_button_new_with_label("Click me");
>       gtk_signal_connect(GTK_OBJECT(button),"clicked",
>                          GTK_SIGNAL_FUNC(on_button_clicked),buffer);
>                          
>       gtk_box_pack_end(GTK_BOX(vbox),button,FALSE,FALSE,3);
>       
>       gtk_widget_show(button);
>       gtk_widget_show(window);
> 
>       gdk_threads_enter ();
>       gtk_main();
>       gdk_threads_leave ();
> 
>       return 0;
> }


_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to