GTK+ Forums Forum Index GTK+ Forums
Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Threading Question

 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming
Author Message
k_rock923



Joined: 25 Apr 2008
Posts: 4

PostPosted: Sun Apr 27, 2008 10:31 pm    Post subject: Threading Question Reply with quote

Hi, I'm having some problems with threads. I think that my problem is with the global lock. I'm trying to update a progress bar by continually pulsing it in a thread while another thread waits for an incoming network connection. Both of these are separate from the main thread. However, I don't see any of the GTK output until the function gui_get_opponent returns. I do see printf statements if I put them in there. Am I missing something obvious here?

Code: (C)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#include "checkers.h"
#include "check_net.h"
#include "check_gui.h"
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main( int argc, char ** argv )
{
    /* The checkers game */
   
struct checkers_game * game = new_checkers_game();

    /* Initialize Threading */
   
g_thread_init( NULL );
    gdk_threads_init( );

    /* Initialize GTK+ */
   
gtk_init( &argc, &argv );

    /* Setup the game, which sets the name
     * and finds an opponent */
   
if( gui_game_setup( game ) == -1 ) { return 0; }

    /* Get an opponent in a new thread */

    /* Send control off to GTK+ */
   
gtk_main();

    return 0;
}


int
gui_game_setup( struct checkers_game * game )
{
    /* create the game */
   
game = new_checkers_game();

    /* Get the username.  This doesn't need to be in
     * another thread */
   
gdk_threads_enter();
    if( gui_get_username( game ) == -1 ) { return -1; }
    gdk_threads_leave();

    g_thread_join( g_thread_create( gui_get_opponent, game, TRUE, NULL ) );
    return 0;
}

int
gui_get_username( struct checkers_game * game )
{
    /* We'll need to create a dialog box for getting
     * the information */
   
GtkWidget* dialog;
    GtkWidget* text;
    GtkWidget* label;

    /* result holds the status of the box */
   
gint result = GTK_RESPONSE_ACCEPT;

    /* Pointer to hold the location of the text from the dialog */
   
const gchar * response = NULL;

    /* Create the widgets */
   
dialog = gtk_dialog_new_with_buttons( "Name?",
                                          NULL,
                                          GTK_DIALOG_MODAL,
                                          GTK_STOCK_CANCEL,
                                          GTK_RESPONSE_CANCEL,
                                          GTK_STOCK_OK,
                                          GTK_RESPONSE_ACCEPT,
                                          NULL );

    text  = gtk_entry_new( );
    label = gtk_label_new( "Please enter your name:  " );

    /* Ensure that the user can only enter so many characters */
   
gtk_entry_set_max_length( GTK_ENTRY( text ), MAX_NAME_LENGTH );

    /* Add the label and text entry field to the dialog's vbox */
   
gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog )->vbox ), label );
    gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog )->vbox ), text );

    /* Ensure that any activity on text field will activate the dialog */
   
gtk_dialog_set_default_response( GTK_DIALOG( dialog ),
                                     GTK_RESPONSE_ACCEPT );
    gtk_entry_set_activates_default( GTK_ENTRY( text ), TRUE );

    /* Ensure that the window is centered on screen */
   
gtk_window_set_position( GTK_WINDOW( dialog ), GTK_WIN_POS_CENTER );

    /* Show the text field inside the box */
   
gtk_widget_show( GTK_WIDGET( label ) );
    gtk_widget_show( GTK_WIDGET( text ) );

    /* Show the dialog */
   
do
   
{
        result   = gtk_dialog_run( GTK_DIALOG( dialog ) );

        if( result == GTK_RESPONSE_CANCEL )
        {
            return -1;
        }

        response = gtk_entry_get_text( GTK_ENTRY( text ) );
    } while( result != GTK_RESPONSE_ACCEPT || strlen( response ) <= 0 );

    /* Copy the name to the struct */
   
strncpy( game->player_name, response, MAX_NAME_LENGTH + 1 );

    /* clean up */
   
gtk_widget_hide( GTK_WIDGET( dialog ) );
    gtk_widget_destroy( GTK_WIDGET( label ) );
    gtk_widget_destroy( GTK_WIDGET( text ) );
    gtk_widget_destroy( GTK_WIDGET( dialog ) );

    return 0;
}

gpointer
gui_get_opponent( gpointer data )
{
    /* The widgets we'll need to make the window */
   
GtkWidget* window;
    GtkWidget* box;
    GtkWidget* progress;
    GtkWidget* cancel;
    GtkWidget* label;
    GThread*   thread;

    /* The checkers game */
   
struct checkers_game * game = ( struct checkers_game * ) data;

    /* The info for telling us when the thread is done */
   
struct gui_pulse_struct * info = malloc(
        sizeof( struct gui_pulse_struct ) );

    gdk_threads_enter();

    /* Create the widgets */
   
window   = gtk_window_new( GTK_WINDOW_POPUP );
    box      = gtk_vbox_new( FALSE, 10 );
    progress = gtk_progress_bar_new( );
    cancel   = gtk_button_new_from_stock( GTK_STOCK_CANCEL );
    label    = gtk_label_new( "Please wait while we find you an opponent" );

    /* Pack up the box and add the box to the window */
   
gtk_container_add( GTK_CONTAINER( box ), label );
    gtk_container_add( GTK_CONTAINER( box ), progress );
    gtk_container_add( GTK_CONTAINER( box ), cancel );
    gtk_container_add( GTK_CONTAINER( window ), box );

    /* Center the window */
   
gtk_window_set_position( GTK_WINDOW( window ), GTK_WIN_POS_CENTER );

    /* show the window on the screen */
   
gtk_widget_show_all( GTK_WIDGET( window ) );
    gdk_threads_leave();

    /* Set up our struct and create the thread */
   
info->widget = progress;
    info->again  = TRUE;

    thread = g_thread_create( gui_pulse_thread, info, TRUE, NULL );

    sleep( 3 );
    get_opponent( game );
    info->again = FALSE;

    g_thread_join( thread );

    free( info );
    return NULL;
}

gpointer
gui_pulse_thread( gpointer data )
{
    struct gui_pulse_struct * info = ( struct gui_pulse_struct * ) data;

    gdk_threads_enter();
    while( info->again == TRUE )
    {
        gtk_progress_bar_pulse( GTK_PROGRESS_BAR( info->widget ) );
        gdk_flush();
        usleep( 1500000 );
    }
    gdk_threads_leave();
}
Back to top
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming All times are GMT
Page 1 of 1

 


Powered by phpBB © 2001, 2005 phpBB Group
CodeBB 1.0 Beta 2
Protected by Anti-Spam ACP