mirror of
https://github.com/transmission/transmission
synced 2025-03-04 02:28:03 +00:00
sync our shutdown code to BentMyWookie's latest tr_close() changes.
This commit is contained in:
parent
4792788d24
commit
14bd1d7408
3 changed files with 35 additions and 163 deletions
118
gtk/main.c
118
gtk/main.c
|
@ -110,13 +110,7 @@ struct cbdata {
|
|||
GList * errqueue;
|
||||
};
|
||||
|
||||
struct exitdata {
|
||||
struct cbdata * cbdata;
|
||||
time_t started;
|
||||
guint timer;
|
||||
};
|
||||
|
||||
#define CBDATA_PTR "callback-data-pointer"
|
||||
#define CBDATA_PTR "callback-data-pointer"
|
||||
|
||||
static GtkUIManager * myUIManager = NULL;
|
||||
|
||||
|
@ -133,8 +127,6 @@ static void
|
|||
makeicon( struct cbdata * cbdata );
|
||||
static void
|
||||
wannaquit( void * vdata );
|
||||
static gboolean
|
||||
exitcheck(gpointer gdata);
|
||||
static void
|
||||
setupdrag(GtkWidget *widget, struct cbdata *data);
|
||||
static void
|
||||
|
@ -255,6 +247,7 @@ main( int argc, char ** argv )
|
|||
g_set_application_name( _( "Transmission" ) );
|
||||
|
||||
/* initialize gtk */
|
||||
g_thread_init( NULL );
|
||||
gtk_init_with_args( &argc, &argv, _("[torrent files]"), entries, domain, NULL );
|
||||
myUIManager = gtk_ui_manager_new ();
|
||||
actions_init ( myUIManager, cbdata );
|
||||
|
@ -412,92 +405,49 @@ makeicon( struct cbdata * cbdata )
|
|||
cbdata->icon = tr_icon_new( );
|
||||
}
|
||||
|
||||
static void
|
||||
wannaquit( void * vdata )
|
||||
static gpointer
|
||||
quitThreadFunc( gpointer gdata )
|
||||
{
|
||||
struct cbdata * data;
|
||||
struct exitdata *edata;
|
||||
struct cbdata * cbdata = gdata;
|
||||
|
||||
data = vdata;
|
||||
if( data->closing )
|
||||
{
|
||||
return;
|
||||
}
|
||||
data->closing = TRUE;
|
||||
tr_close( tr_core_handle( cbdata->core ) );
|
||||
|
||||
/* stop the update timer */
|
||||
if(0 < data->timer)
|
||||
g_source_remove(data->timer);
|
||||
data->timer = 0;
|
||||
|
||||
/* pause torrents and stop nat traversal */
|
||||
tr_core_shutdown( data->core );
|
||||
|
||||
/* set things up to wait for torrents to stop */
|
||||
edata = g_new0(struct exitdata, 1);
|
||||
edata->cbdata = data;
|
||||
edata->started = time(NULL);
|
||||
/* check if torrents are still running */
|
||||
if(exitcheck(edata)) {
|
||||
/* yes, start the exit timer and disable widgets */
|
||||
edata->timer = g_timeout_add(EXIT_CHECK_INTERVAL, exitcheck, edata);
|
||||
if( NULL != data->wind )
|
||||
{
|
||||
gtk_widget_set_sensitive( GTK_WIDGET( data->wind ), FALSE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
exitcheck( gpointer gdata )
|
||||
{
|
||||
struct exitdata * edata;
|
||||
struct cbdata * cbdata;
|
||||
|
||||
edata = gdata;
|
||||
cbdata = edata->cbdata;
|
||||
|
||||
/* keep waiting until we're ready to quit or we hit the exit timeout */
|
||||
if( time( NULL ) - edata->started < TRACKER_EXIT_TIMEOUT )
|
||||
{
|
||||
if( !tr_core_quiescent( cbdata->core ) )
|
||||
{
|
||||
updatemodel( cbdata );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* exit otherwise */
|
||||
if( 0 < edata->timer )
|
||||
{
|
||||
g_source_remove( edata->timer );
|
||||
}
|
||||
g_free( edata );
|
||||
/* note that cbdata->prefs holds a reference to cbdata->core, and
|
||||
it's destruction may trigger callbacks that use cbdata->core */
|
||||
if( NULL != cbdata->prefs )
|
||||
{
|
||||
/* shutdown the gui */
|
||||
if( cbdata->prefs )
|
||||
gtk_widget_destroy( GTK_WIDGET( cbdata->prefs ) );
|
||||
}
|
||||
if( NULL != cbdata->wind )
|
||||
{
|
||||
if( cbdata->wind )
|
||||
gtk_widget_destroy( GTK_WIDGET( cbdata->wind ) );
|
||||
}
|
||||
g_object_unref( cbdata->core );
|
||||
if( NULL != cbdata->icon )
|
||||
{
|
||||
if( cbdata->icon )
|
||||
g_object_unref( cbdata->icon );
|
||||
}
|
||||
g_assert( 0 == cbdata->timer );
|
||||
if( NULL != cbdata->errqueue )
|
||||
{
|
||||
g_list_foreach( cbdata->errqueue, (GFunc) g_free, NULL );
|
||||
if( cbdata->errqueue ) {
|
||||
g_list_foreach( cbdata->errqueue, (GFunc)g_free, NULL );
|
||||
g_list_free( cbdata->errqueue );
|
||||
}
|
||||
g_free( cbdata );
|
||||
gtk_main_quit();
|
||||
|
||||
return FALSE;
|
||||
/* exit the gtk main loop */
|
||||
gtk_main_quit( );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
wannaquit( void * vdata )
|
||||
{
|
||||
struct cbdata * cbdata = vdata;
|
||||
|
||||
/* stop the update timer */
|
||||
if( cbdata->timer ) {
|
||||
g_source_remove( cbdata->timer );
|
||||
cbdata->timer = 0;
|
||||
}
|
||||
|
||||
/* freeze the gui */
|
||||
if( cbdata->wind )
|
||||
gtk_widget_set_sensitive( GTK_WIDGET( cbdata->wind ), FALSE );
|
||||
|
||||
/* shut down libT */
|
||||
g_thread_create( quitThreadFunc, vdata, TRUE, NULL );
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -122,39 +122,12 @@ tr_core_dispose( GObject * obj )
|
|||
{
|
||||
TrCore * self = (TrCore *) obj;
|
||||
GObjectClass * parent;
|
||||
GtkTreeIter iter;
|
||||
TrTorrent * tor;
|
||||
|
||||
if( self->disposed )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->disposed = TRUE;
|
||||
|
||||
pref_save( NULL );
|
||||
|
||||
#ifdef REFDBG
|
||||
fprintf( stderr, "core %p dispose\n", self );
|
||||
#endif
|
||||
|
||||
/* sever all remaining torrents in the model */
|
||||
if( gtk_tree_model_get_iter_first( self->model, &iter ) ) do
|
||||
{
|
||||
gtk_tree_model_get( self->model, &iter, MC_TORRENT, &tor, -1 );
|
||||
tr_torrent_sever( tor );
|
||||
g_object_unref( tor );
|
||||
}
|
||||
while( gtk_tree_model_iter_next( self->model, &iter ) );
|
||||
g_object_unref( self->model );
|
||||
|
||||
#ifdef REFDBG
|
||||
fprintf( stderr, "core %p dead\n", self );
|
||||
#endif
|
||||
|
||||
/* close the libtransmission instance */
|
||||
tr_close( self->handle );
|
||||
|
||||
/* Chain up to the parent class */
|
||||
parent = g_type_class_peek( g_type_parent( TR_CORE_TYPE ) );
|
||||
parent->dispose( obj );
|
||||
}
|
||||
|
@ -373,49 +346,6 @@ tr_core_handle( TrCore * self )
|
|||
return self->disposed ? NULL : self->handle;
|
||||
}
|
||||
|
||||
void
|
||||
tr_core_shutdown( TrCore * self )
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
TR_IS_CORE( self );
|
||||
|
||||
if( self->disposed )
|
||||
return;
|
||||
|
||||
g_assert( !self->quitting );
|
||||
self->quitting = TRUE;
|
||||
|
||||
/* try to stop all the torrents nicely */
|
||||
if ( gtk_tree_model_get_iter_first( self->model, &iter) ) do {
|
||||
TrTorrent * tor;
|
||||
gtk_tree_model_get( self->model, &iter, MC_TORRENT, &tor, -1 );
|
||||
tr_torrent_sever( tor );
|
||||
g_object_unref( tor );
|
||||
} while( gtk_list_store_remove( GTK_LIST_STORE(self->model), &iter ) );
|
||||
|
||||
/* shut down nat traversal */
|
||||
tr_natTraversalEnable( self->handle, 0 );
|
||||
}
|
||||
|
||||
gboolean
|
||||
tr_core_quiescent( TrCore * self )
|
||||
{
|
||||
const tr_handle_status * hstat;
|
||||
|
||||
TR_IS_CORE( self );
|
||||
g_assert( self->quitting );
|
||||
|
||||
if( self->disposed )
|
||||
return TRUE;
|
||||
|
||||
if ( tr_torrentCount( self->handle ) != 0 )
|
||||
return FALSE;
|
||||
|
||||
hstat = tr_handleStatus( self->handle );
|
||||
return TR_NAT_TRAVERSAL_DISABLED == hstat->natTraversalStatus;
|
||||
}
|
||||
|
||||
static void
|
||||
tr_core_insert( TrCore * self, TrTorrent * tor )
|
||||
{
|
||||
|
|
|
@ -109,14 +109,6 @@ tr_core_model( TrCore * self );
|
|||
tr_handle *
|
||||
tr_core_handle( TrCore * self );
|
||||
|
||||
/* Try to politely stop all torrents and nat traversal */
|
||||
void
|
||||
tr_core_shutdown( TrCore * self );
|
||||
|
||||
/* Returns true if the shutdown has completed */
|
||||
gboolean
|
||||
tr_core_quiescent( TrCore * self );
|
||||
|
||||
/* Load saved state, return number of torrents added. May trigger one
|
||||
or more "error" signals with TR_CORE_ERR_ADD_TORRENT */
|
||||
int
|
||||
|
|
Loading…
Add table
Reference in a new issue