setupdrag( GTK_WIDGET( wind ), cbdata );
}
-static gpointer
-quitThreadFunc( gpointer gdata )
+static gboolean
+onSessionClosed( gpointer gdata )
{
struct cbdata * cbdata = gdata;
- gdk_threads_enter( );
-
- tr_core_close( cbdata->core );
/* shutdown the gui */
if( cbdata->details ) {
g_free( cbdata );
gtk_main_quit( );
- gdk_threads_leave( );
+ return FALSE;
+}
+
+static gpointer
+sessionCloseThreadFunc( 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( );
+ tr_core_close( cbdata->core );
+ gtr_idle_add( onSessionClosed, gdata );
+ gdk_threads_leave( );
return NULL;
}
pref_int_get( PREF_KEY_MAIN_WINDOW_Y ) );
/* shut down libT */
- g_thread_create( quitThreadFunc, vdata, TRUE, NULL );
+ g_thread_create( sessionCloseThreadFunc, vdata, TRUE, NULL );
}
static void
return tr_date( ) >= deadline;
}
-#define SHUTDOWN_MAX_SECONDS 30
+#define SHUTDOWN_MAX_SECONDS 20
void
tr_sessionClose( tr_session * session )
tr_runInEventThread( session, sessionCloseImpl, session );
while( !session->isClosed && !deadlineReached( deadline ) )
{
- dbgmsg(
- "waiting for the shutdown commands to run in the main thread" );
+ dbgmsg( "waiting for the libtransmission thread to finish" );
tr_wait( 100 );
}
/* close the libtransmission thread */
tr_eventClose( session );
- while( session->events && !deadlineReached( deadline ) )
+ while( session->events != NULL )
{
- dbgmsg( "waiting for the libevent thread to shutdown cleanly" );
+ static tr_bool forced = FALSE;
+ dbgmsg( "waiting for libtransmission thread to finish" );
tr_wait( 100 );
+ if( deadlineReached( deadline ) && !forced )
+ {
+ event_loopbreak( );
+ forced = TRUE;
+ }
}
/* free the session memory */