Threads...
- From: Christian Schaubschlaeger <cs gup uni-linz ac at>
- To: gtk-list gnome org
- Subject: Threads...
- Date: Tue, 25 Jul 2006 18:00:21 +0200
Hello!
I have kind of a conceptual problem concerning a multithreaded app.
Let me describe the following small scenario:
Below you can see a very simple gtk+ program (or at least the important
parts of it). In the main function the threads environment is initialized,
then a "dialog_init" is created and shown:
int main(int argc, char **argv)
{
if (!g_thread_supported ())
{
g_thread_init (NULL);
gdk_threads_init();
printf("Threads initialized\n");
}
else
{
printf("Threads not supported!\n");
exit(1);
}
gtk_init(&argc, &argv);
dialog_init = create_dialog_init();
gtk_widget_show(dialog_init);
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
}
The purpose of this "dialog_init" is to
1) call the function "init_app()", which does the actual initialization stuff
(which takes a long time), and
2) display and update a progress bar until init_app() is finished.
I have implemented this in the following way, which actually works fine:
void on_dialog_init_show()
{
...
g_timeout_add(10,on_dialog_init_login_update_pb,NULL);
g_init = g_thread_create(t_init,NULL,FALSE,&error);
}
gboolean on_dialog_init_login_update_pb(gpointer data)
{
... update the progress bar...
if (init_finished) return FALSE;
else return TRUE;
}
void *t_init(void *p)
{
init_app();
init_finished = 1; // global var, indicates that init_app() has finished
return NULL;
}
on_dialog_init_login_update_pb is called periodically and updates the pb,
until init_app is finished.
Now during initialization it is necessary to occasionally popup messageboxes,
ie. it might be the case, that from somewhere within init_app() a messagebox
is shown.
init_app() is a function which doesn't know anything about gtk+ (since I want
it to be independent from a GUI), therefore I provide a callback function
(cb_messagebox) to init_app, which - when called - shows a messagebox.
Since init_app() runs in a separate thread, it is necessary to use
gdk_threads_enter and gdk_threads_leave, therefore I have changed the
thread function to:
void *t_init(void *p)
{
gdk_threads_enter();
init_app(cb_messagebox);
gdk_threads_leave();
init_finished = 1; // global var, indicates that init_app() has finished
return NULL;
}
void cb_messagebox(char *msg_text)
{
// popup a gtk+ messagebox displaying
// msg_text
...
gtk_dialog_run(...);
...
}
Unfortunately now the progress bar is no longer updated, which is quite clear,
since the call to gdk_threads_enter in t_init blocks all 'drawing requests'
from outside this thread, especially those from the progress bar, until
gdk_threads_leave is called.
My question now is: how can I solve or avoid this problem?
I _need_ to popup messageboxes from within init_app (which forces me to use
gdk_threads_enter), but I still want the progress bar to be updated.
What I could do is not to use gdk_threads_enter in t_init, but in
cb_messagebox (before the call to gtk_dialog_run), but this is not a good
soluion, since cb_messagebox is sometimes called from within a separate
thread, and sometimes from within the main process (which inhibits the use of
gdk_threads_enter).
Tricky...
Looking forward for suggestions!
Thanks!
Christian
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]