From 5877747ad6d0bd0ac3a5789c73dee51db239bb54 Mon Sep 17 00:00:00 2001 From: Jordan Lee Date: Fri, 4 Jan 2013 06:57:39 +0000 Subject: [PATCH] (gtk) #5203 transmission-gtk shouldn't use gdk_threads_enter() and gdk_threads_leave() -- on shutdown, destruct the TrCore GObject in the glib thread, and then call tr_sessionClose() from a worker thread. --- gtk/main.c | 27 ++++++++++++++++++--------- gtk/tr-core.c | 5 +++-- gtk/tr-core.h | 2 +- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/gtk/main.c b/gtk/main.c index f600f3e78..e23422f8c 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -884,17 +884,22 @@ on_session_closed (gpointer gdata) return FALSE; } +struct session_close_struct +{ + tr_session * session; + struct cbdata * cbdata; +}; + +/* since tr_sessionClose () is a blocking function, + * delegate its call to another thread here... when it's done, + * punt the GUI teardown back to the GTK+ thread */ static gpointer session_close_threadfunc (gpointer gdata) { - /* since tr_sessionClose () is a blocking function, - * call it from another thread... when it's done, - * punt the GUI teardown back to the GTK+ thread */ - struct cbdata * cbdata = gdata; - gdk_threads_enter (); - gtr_core_close (cbdata->core); - gdk_threads_add_idle (on_session_closed, gdata); - gdk_threads_leave (); + struct session_close_struct * data = gdata; + tr_sessionClose (data->session); + gdk_threads_add_idle (on_session_closed, data->cbdata); + g_free (data); return NULL; } @@ -909,6 +914,7 @@ on_app_exit (gpointer vdata) { GtkWidget *r, *p, *b, *w, *c; struct cbdata *cbdata = vdata; + struct session_close_struct * session_close_data; /* stop the update timer */ if (cbdata->timer) @@ -960,7 +966,10 @@ on_app_exit (gpointer vdata) gtr_pref_int_get (TR_KEY_main_window_y)); /* shut down libT */ - g_thread_new ("shutdown-thread", session_close_threadfunc, vdata); + session_close_data = g_new (struct session_close_struct, 1); + session_close_data->cbdata = cbdata; + session_close_data->session = gtr_core_close (cbdata->core); + g_thread_new ("shutdown-thread", session_close_threadfunc, session_close_data); } static void diff --git a/gtk/tr-core.c b/gtk/tr-core.c index f7e216a74..48a1d0d83 100644 --- a/gtk/tr-core.c +++ b/gtk/tr-core.c @@ -871,7 +871,7 @@ gtr_core_new (tr_session * session) return core; } -void +tr_session * gtr_core_close (TrCore * core) { tr_session * session = gtr_core_session (core); @@ -880,8 +880,9 @@ gtr_core_close (TrCore * core) { core->priv->session = NULL; gtr_pref_save (session); - tr_sessionClose (session); } + + return session; } /*** diff --git a/gtk/tr-core.h b/gtk/tr-core.h index c47f400c1..08edaabf5 100644 --- a/gtk/tr-core.h +++ b/gtk/tr-core.h @@ -69,7 +69,7 @@ GType tr_core_get_type (void) G_GNUC_CONST; TrCore * gtr_core_new (tr_session *); -void gtr_core_close (TrCore*); +tr_session * gtr_core_close (TrCore*); /* Return the model used without incrementing the reference count */ GtkTreeModel * gtr_core_model (TrCore * self);