from inside your init routine, whenever you require your message box: g_idle_add() a function to make the message box. this function should be gtk+ library aware and your message box will be made without problems. and that's it. richard On Jul 25, 2006, at 6:00 PM, Christian Schaubschlaeger wrote: > > 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 > > _______________________________________________ > > gtk-list@xxxxxxxxx > http://mail.gnome.org/mailman/listinfo/gtk-list > _______________________________________________ gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list