1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-03 18:25:35 +00:00

sync our shutdown code to BentMyWookie's latest tr_close() changes.

This commit is contained in:
Charles Kerr 2007-11-09 16:11:10 +00:00
parent 4792788d24
commit 14bd1d7408
3 changed files with 35 additions and 163 deletions

View file

@ -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

View file

@ -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 )
{

View file

@ -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