priv->self = self;
priv->interactive = TRUE;
- priv->protect = FALSE;
priv->styles = g_new0(StyleSet,1);
priv->glk_styles = g_new0(StyleSet,1);
priv->final_message = g_strdup("[ The game has finished ]");
- priv->running = FALSE;
- priv->program = NULL;
- priv->thread = NULL;
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->abort_signalled = FALSE;
- 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->needs_rearrange = FALSE;
- priv->ignore_next_arrange_event = FALSE;
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_map = NULL;
- priv->resource_lock = g_mutex_new();
- priv->resource_loaded = g_cond_new();
- priv->resource_info_available = g_cond_new();
- priv->resource_load_callback = NULL;
- priv->resource_load_callback_data = NULL;
- priv->image_cache = NULL;
- priv->program_name = NULL;
- priv->program_info = NULL;
- priv->story_name = NULL;
- priv->interrupt_handler = NULL;
- priv->root_window = NULL;
- priv->fileref_list = NULL;
- priv->current_stream = NULL;
- priv->stream_list = NULL;
- priv->timer_id = 0;
- priv->in_startup = FALSE;
- priv->current_dir = NULL;
+
+ 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);
}
{
ChimaraGlk *self = CHIMARA_GLK(object);
CHIMARA_GLK_USE_PRIVATE(self, priv);
+ priv->after_finalize = TRUE;
/* Free widget properties */
g_free(priv->final_message);
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 */
/* 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)
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);
}
}
ChimaraGlkPrivate *glk_data;
};
+static void
+free_startup_data(struct StartupData *startup)
+{
+ int i = 0;
+ while(i < startup->args.argc)
+ g_free(startup->args.argv[i++]);
+ g_free(startup->args.argv);
+}
+
/* glk_enter() is the actual function called in the new thread in which glk_main() runs. */
static gpointer
glk_enter(struct StartupData *startup)
startup->glk_data->in_startup = TRUE;
int result = startup->glkunix_startup_code(&startup->args);
startup->glk_data->in_startup = FALSE;
-
- int i = 0;
- while(i < startup->args.argc)
- g_free(startup->args.argv[i++]);
- g_free(startup->args.argv);
-
- if(!result)
+
+ if(!result) {
+ free_startup_data(startup);
return NULL;
+ }
}
/* Run main function */
g_free(startup);
g_signal_emit_by_name(startup->glk_data->self, "started");
glk_main();
+ free_startup_data(startup);
glk_exit(); /* Run shutdown code in glk_exit() even if glk_main() returns normally */
g_assert_not_reached(); /* because glk_exit() calls g_thread_exit() */
return NULL;
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);
}
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);
}
}