]> granicus.if.org Git - transmission/commitdiff
(trunk) #1663 "crashes on shutdown if libevent loop doesn't exit soon enough" --...
authorCharles Kerr <charles@transmissionbt.com>
Mon, 30 Nov 2009 04:58:03 +0000 (04:58 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Mon, 30 Nov 2009 04:58:03 +0000 (04:58 +0000)
gtk/main.c
libtransmission/session.c

index a106633b79d75580b9720a12d3edf63fa501674d..210e09b866be0367e611e31955fcabca3b57973d 100644 (file)
@@ -701,13 +701,10 @@ winsetup( struct cbdata * cbdata,
     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 ) {
@@ -732,8 +729,21 @@ quitThreadFunc( gpointer gdata )
     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;
 }
 
@@ -800,7 +810,7 @@ wannaquit( gpointer vdata )
                                    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
index 9e398c67dd890c4db341e3f9aa06cd266164bb9a..b69fff6c8f4e1714ba24852d58617948697e3d35 100644 (file)
@@ -1586,7 +1586,7 @@ deadlineReached( const uint64_t deadline )
     return tr_date( ) >= deadline;
 }
 
-#define SHUTDOWN_MAX_SECONDS 30
+#define SHUTDOWN_MAX_SECONDS 20
 
 void
 tr_sessionClose( tr_session * session )
@@ -1602,8 +1602,7 @@ 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 );
     }
 
@@ -1623,10 +1622,16 @@ tr_sessionClose( tr_session * session )
 
     /* 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 */