X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=libchimara%2Fchimara-glk.c;h=540639a066adb69a556d17259e12a1168cfdb273;hb=a03ca60f975be1f4636e42ca19f9e6eafc3fad12;hp=584401763ba98cc00b933bbee11c3338ed94245a;hpb=41d8af5945b52368aef20ce2cf272c5a327c57e1;p=projects%2Fchimara%2Fchimara.git diff --git a/libchimara/chimara-glk.c b/libchimara/chimara-glk.c index 5844017..540639a 100644 --- a/libchimara/chimara-glk.c +++ b/libchimara/chimara-glk.c @@ -51,18 +51,12 @@ * url="http://www.gnu.org/software/libtool/manual/html_node/Finding-the-dlname.html"> * Libtool manual). * - * You need to initialize multithreading in any program you use a #ChimaraGlk - * widget in. This means including the following incantation at the beginning - * of your program: - * |[ - * if(!g_thread_supported()) - * g_thread_init(NULL); - * gdk_threads_init(); - * ]| - * This initialization must take place before the call to - * gtk_init(). In addition to this, you must also protect your call to - * gtk_main() by calling gdk_threads_enter() right before it, and - * gdk_threads_leave() right after it. + * You need to initialize GDK threading in any program you use a #ChimaraGlk + * widget in. + * This means calling gdk_threads_init() at the beginning of your program, + * before the call to gtk_init(). + * In addition to this, you must also protect your call to gtk_main() by calling + * gdk_threads_enter() right before it, and gdk_threads_leave() right after it. * * The following sample program shows how to initialize and construct a simple * GTK window that runs a Glk program: @@ -79,8 +73,6 @@ * gchar *plugin_argv[] = { "plugin.so", "-option" }; * * /* Initialize threads and GTK */ - * if(!g_thread_supported()) - * g_thread_init(NULL); * gdk_threads_init(); * gtk_init(&argc, &argv); * @@ -162,20 +154,22 @@ chimara_glk_init(ChimaraGlk *self) priv->glk_styles = g_new0(StyleSet,1); priv->final_message = g_strdup("[ The game has finished ]"); priv->event_queue = g_queue_new(); - priv->event_lock = g_mutex_new(); - priv->event_queue_not_empty = g_cond_new(); - priv->event_queue_not_full = g_cond_new(); - priv->abort_lock = g_mutex_new(); - priv->shutdown_lock = g_mutex_new(); - priv->shutdown_key_pressed = g_cond_new(); - priv->arrange_lock = g_mutex_new(); - priv->rearranged = g_cond_new(); priv->char_input_queue = g_async_queue_new(); priv->line_input_queue = g_async_queue_new(); /* FIXME Should be g_async_queue_new_full(g_free); but only in GTK >= 2.16 */ - priv->resource_lock = g_mutex_new(); - priv->resource_loaded = g_cond_new(); - priv->resource_info_available = g_cond_new(); + + g_mutex_init(&priv->event_lock); + g_mutex_init(&priv->abort_lock); + g_mutex_init(&priv->shutdown_lock); + g_mutex_init(&priv->arrange_lock); + g_mutex_init(&priv->resource_lock); + + g_cond_init(&priv->event_queue_not_empty); + g_cond_init(&priv->event_queue_not_full); + g_cond_init(&priv->shutdown_key_pressed); + g_cond_init(&priv->rearranged); + g_cond_init(&priv->resource_loaded); + g_cond_init(&priv->resource_info_available); style_init(self); } @@ -239,6 +233,7 @@ chimara_glk_finalize(GObject *object) { ChimaraGlk *self = CHIMARA_GLK(object); CHIMARA_GLK_USE_PRIVATE(self, priv); + priv->after_finalize = TRUE; /* Free widget properties */ g_free(priv->final_message); @@ -249,36 +244,38 @@ chimara_glk_finalize(GObject *object) g_hash_table_destroy(priv->glk_styles->text_grid); /* Free the event queue */ - g_mutex_lock(priv->event_lock); + g_mutex_lock(&priv->event_lock); g_queue_foreach(priv->event_queue, (GFunc)g_free, NULL); g_queue_free(priv->event_queue); - g_cond_free(priv->event_queue_not_empty); - g_cond_free(priv->event_queue_not_full); + g_cond_clear(&priv->event_queue_not_empty); + g_cond_clear(&priv->event_queue_not_full); priv->event_queue = NULL; - g_mutex_unlock(priv->event_lock); - g_mutex_free(priv->event_lock); + g_mutex_unlock(&priv->event_lock); + g_mutex_clear(&priv->event_lock); + /* Free the abort signaling mechanism */ - g_mutex_lock(priv->abort_lock); + g_mutex_lock(&priv->abort_lock); /* Make sure no other thread is busy with this */ - g_mutex_unlock(priv->abort_lock); - g_mutex_free(priv->abort_lock); - priv->abort_lock = NULL; + g_mutex_unlock(&priv->abort_lock); + g_mutex_clear(&priv->abort_lock); + /* Free the shutdown keypress signaling mechanism */ - g_mutex_lock(priv->shutdown_lock); - g_cond_free(priv->shutdown_key_pressed); - g_mutex_unlock(priv->shutdown_lock); - priv->shutdown_lock = NULL; + g_mutex_lock(&priv->shutdown_lock); + g_cond_clear(&priv->shutdown_key_pressed); + g_mutex_unlock(&priv->shutdown_lock); + g_mutex_clear(&priv->shutdown_lock); + /* Free the window arrangement signaling */ - g_mutex_lock(priv->arrange_lock); - g_cond_free(priv->rearranged); - g_mutex_unlock(priv->arrange_lock); - g_mutex_free(priv->arrange_lock); - priv->arrange_lock = NULL; - g_mutex_lock(priv->resource_lock); - g_cond_free(priv->resource_loaded); - g_cond_free(priv->resource_info_available); - g_mutex_unlock(priv->resource_lock); - g_mutex_free(priv->resource_lock); + g_mutex_lock(&priv->arrange_lock); + g_cond_clear(&priv->rearranged); + g_mutex_unlock(&priv->arrange_lock); + g_mutex_clear(&priv->arrange_lock); + + g_mutex_lock(&priv->resource_lock); + g_cond_clear(&priv->resource_loaded); + g_cond_clear(&priv->resource_info_available); + g_mutex_unlock(&priv->resource_lock); + g_mutex_clear(&priv->resource_lock); g_slist_foreach(priv->image_cache, (GFunc)clear_image_cache, NULL); g_slist_free(priv->image_cache); /* Unref input queues (this should destroy them since any Glk thread has stopped by now */ @@ -561,7 +558,7 @@ chimara_glk_size_allocate(GtkWidget *widget, GtkAllocation *allocation) /* arrange points to a window that contains all text grid and graphics windows which have been resized */ - g_mutex_lock(priv->arrange_lock); + g_mutex_lock(&priv->arrange_lock); if(!priv->ignore_next_arrange_event) { if(arrange) @@ -570,8 +567,8 @@ chimara_glk_size_allocate(GtkWidget *widget, GtkAllocation *allocation) else priv->ignore_next_arrange_event = FALSE; priv->needs_rearrange = FALSE; - g_cond_signal(priv->rearranged); - g_mutex_unlock(priv->arrange_lock); + g_cond_signal(&priv->rearranged); + g_mutex_unlock(&priv->arrange_lock); } } @@ -1123,8 +1120,8 @@ glk_main() runs. Takes ownership of @startup and will free it. */ static gpointer glk_enter(struct StartupData *startup) { - extern GPrivate *glk_data_key; - g_private_set(glk_data_key, startup->glk_data); + extern GPrivate glk_data_key; + g_private_set(&glk_data_key, startup->glk_data); /* Acquire the Glk thread's references to the input queues */ g_async_queue_ref(startup->glk_data->char_input_queue); @@ -1231,8 +1228,8 @@ chimara_glk_run(ChimaraGlk *glk, const gchar *plugin, int argc, char *argv[], GE g_object_notify(G_OBJECT(glk), "program-name"); /* Run in a separate thread */ - priv->thread = g_thread_create((GThreadFunc)glk_enter, startup, TRUE, error); - + priv->thread = g_thread_try_new("glk", (GThreadFunc)glk_enter, startup, error); + return !(priv->thread == NULL); } @@ -1285,16 +1282,16 @@ chimara_glk_stop(ChimaraGlk *glk) if(!priv->running) return; - if(priv->abort_lock) { - g_mutex_lock(priv->abort_lock); + if(!priv->after_finalize) { + g_mutex_lock(&priv->abort_lock); priv->abort_signalled = TRUE; - g_mutex_unlock(priv->abort_lock); + g_mutex_unlock(&priv->abort_lock); /* Stop blocking on the event queue condition */ event_throw(glk, evtype_Abort, NULL, 0, 0); /* Stop blocking on the shutdown key press condition */ - g_mutex_lock(priv->shutdown_lock); - g_cond_signal(priv->shutdown_key_pressed); - g_mutex_unlock(priv->shutdown_lock); + g_mutex_lock(&priv->shutdown_lock); + g_cond_signal(&priv->shutdown_key_pressed); + g_mutex_unlock(&priv->shutdown_lock); } }