Some minor code cleanups.

Handle things a little better when quitting.
This commit is contained in:
Josh Elsasser 2006-05-03 10:09:11 +00:00
parent 229d9c84dc
commit 49fccfd96e
7 changed files with 87 additions and 114 deletions

View File

@ -25,7 +25,6 @@
*/
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@ -341,14 +340,14 @@ cf_benc_append(benc_val_t *val, char type, int incsize) {
const char *
cf_getpref(const char *name) {
assert(NULL != gl_prefs);
g_assert(NULL != gl_prefs);
return g_tree_lookup(gl_prefs, name);
}
void
cf_setpref(const char *name, const char *value) {
assert(NULL != gl_prefs);
g_assert(NULL != gl_prefs);
g_tree_insert(gl_prefs, g_strdup(name), g_strdup(value));
}

View File

@ -24,7 +24,6 @@
POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@ -173,7 +172,7 @@ makeprefwindow(GtkWindow *parent, TrBackend *back, gboolean *opened) {
ii++;
#undef RN
assert(rowcount == ii);
g_assert(rowcount == ii);
gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(wind)->vbox), table);
g_signal_connect_data(wind, "response", G_CALLBACK(clickdialog),
@ -495,7 +494,7 @@ makeinfowind(GtkWindow *parent, TrTorrent *tor) {
INFOSEP(table, ii);
assert(rowcount == ii);
g_assert(rowcount == ii);
gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(wind)->vbox), table);
g_signal_connect(G_OBJECT(wind), "response",

View File

@ -27,7 +27,6 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>

View File

@ -25,7 +25,6 @@
*/
#include <sys/param.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
@ -47,8 +46,15 @@
#include "transmission.h"
#include "util.h"
/* time in seconds to wait for torrents to stop when exiting */
#define TRACKER_EXIT_TIMEOUT 5
/* interval in milliseconds to update the torrent list display */
#define UPDATE_INTERVAL 500
/* interval in milliseconds to check for stopped torrents and update display */
#define EXIT_CHECK_INTERVAL 500
struct cbdata {
TrBackend *back;
GtkWindow *wind;
@ -72,6 +78,8 @@ readargs(int argc, char **argv);
void
makewind(GtkWidget *wind, TrBackend *back, benc_val_t *state, GList *args);
void
quittransmission(struct cbdata *data);
GtkWidget *
makewind_toolbar(struct cbdata *data);
GtkWidget *
@ -81,8 +89,6 @@ winclose(GtkWidget *widget, GdkEvent *event, gpointer gdata);
gboolean
exitcheck(gpointer gdata);
void
stoptransmission(struct cbdata *data);
void
setupdrag(GtkWidget *widget, struct cbdata *data);
void
gotdrag(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
@ -162,7 +168,6 @@ actionitems[] = {
#define SIGCOUNT_MAX 3
static sig_atomic_t global_sigcount = 0;
static int global_lastsig = 0;
int
main(int argc, char **argv) {
@ -285,7 +290,7 @@ makewind(GtkWidget *wind, TrBackend *back, benc_val_t *state, GList *args) {
g_object_ref(G_OBJECT(back));
data->back = back;
data->wind = GTK_WINDOW(wind);
data->timer = -1;
data->timer = 0;
/* filled in by makewind_list */
data->model = NULL;
data->view = NULL;
@ -306,6 +311,7 @@ makewind(GtkWidget *wind, TrBackend *back, benc_val_t *state, GList *args) {
gtk_statusbar_push(GTK_STATUSBAR(status), 0, "");
gtk_box_pack_start(GTK_BOX(vbox), status, FALSE, FALSE, 0);
gtk_container_set_focus_child(GTK_CONTAINER(vbox), scroll);
gtk_container_add(GTK_CONTAINER(wind), vbox);
gtk_window_set_title(data->wind, g_get_application_name());
g_signal_connect(G_OBJECT(wind), "delete_event", G_CALLBACK(winclose), data);
@ -314,7 +320,7 @@ makewind(GtkWidget *wind, TrBackend *back, benc_val_t *state, GList *args) {
addtorrents(data, state, args, NULL, NULL);
data->timer = g_timeout_add(500, updatemodel, data);
data->timer = g_timeout_add(UPDATE_INTERVAL, updatemodel, data);
updatemodel(data);
gtk_widget_show_all(vbox);
@ -334,6 +340,19 @@ makewind(GtkWidget *wind, TrBackend *back, benc_val_t *state, GList *args) {
ipc_socket_setup(GTK_WINDOW(wind), addtorrents, data);
}
void
quittransmission(struct cbdata *data) {
g_object_unref(G_OBJECT(data->back));
gtk_widget_destroy(GTK_WIDGET(data->wind));
if(0 < data->timer)
g_source_remove(data->timer);
if(NULL != data->stupidpopuphack)
gtk_widget_destroy(data->stupidpopuphack);
g_free(data->buttons);
g_free(data);
gtk_main_quit();
}
GtkWidget *
makewind_toolbar(struct cbdata *data) {
GtkWidget *bar = gtk_toolbar_new();
@ -388,7 +407,7 @@ makewind_list(struct cbdata *data) {
GtkCellRenderer *namerend, *progrend;
char *str;
assert(MC_ROW_COUNT == ALEN(types));
g_assert(MC_ROW_COUNT == ALEN(types));
store = gtk_list_store_newv(MC_ROW_COUNT, types);
view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
@ -433,35 +452,28 @@ gboolean
winclose(GtkWidget *widget SHUTUP, GdkEvent *event SHUTUP, gpointer gdata) {
struct cbdata *data = gdata;
struct exitdata *edata;
tr_stat_t *st;
GtkTreeIter iter;
TrTorrent *tor;
gboolean going;
unsigned int ii;
if(0 >= data->timer)
/* stop the update timer */
if(0 < data->timer)
g_source_remove(data->timer);
data->timer = -1;
data->timer = 0;
going = gtk_tree_model_get_iter_first(data->model, &iter);
while(going) {
gtk_tree_model_get(data->model, &iter, MC_TORRENT, &tor, -1);
st = tr_torrent_stat(tor);
if(TR_STATUS_ACTIVE & st->status) {
tr_torrentStop(tr_torrent_handle(tor));
going = gtk_tree_model_iter_next(data->model, &iter);
} else {
going = gtk_list_store_remove(GTK_LIST_STORE(data->model), &iter);
}
g_object_unref(G_OBJECT(tor));
}
/* try to stop all the torrents */
tr_backend_stop_torrents(data->back);
/* XXX should disable widgets or something */
/* try to wait until torrents stop before exiting */
/* set things up to wait for torrents to stop */
edata = g_new0(struct exitdata, 1);
edata->cbdata = data;
edata->started = time(NULL);
edata->timer = g_timeout_add(500, exitcheck, edata);
/* 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);
for(ii = 0; ii < ALEN(actionitems); ii++)
gtk_widget_set_sensitive(data->buttons[ii], FALSE);
gtk_widget_set_sensitive(GTK_WIDGET(data->view), FALSE);
}
/* returning FALSE means to destroy the window */
return TRUE;
@ -470,67 +482,23 @@ winclose(GtkWidget *widget SHUTUP, GdkEvent *event SHUTUP, gpointer gdata) {
gboolean
exitcheck(gpointer gdata) {
struct exitdata *data = gdata;
tr_stat_t *st;
GtkTreeIter iter;
TrTorrent *tor;
gboolean go;
go = gtk_tree_model_get_iter_first(data->cbdata->model, &iter);
while(go) {
gtk_tree_model_get(data->cbdata->model, &iter, MC_TORRENT, &tor, -1);
st = tr_torrent_stat(tor);
if(!(TR_STATUS_PAUSE & st->status))
go = gtk_tree_model_iter_next(data->cbdata->model, &iter);
else {
go = gtk_list_store_remove(GTK_LIST_STORE(data->cbdata->model), &iter);
}
g_object_unref(G_OBJECT(tor));
}
/* keep going if we still have torrents and haven't hit the exit timeout */
if(0 < tr_torrentCount(tr_backend_handle(data->cbdata->back)) &&
time(NULL) - data->started < TRACKER_EXIT_TIMEOUT) {
assert(gtk_tree_model_get_iter_first(data->cbdata->model, &iter));
if(time(NULL) - data->started < TRACKER_EXIT_TIMEOUT &&
!tr_backend_torrents_stopped(data->cbdata->back)) {
updatemodel(data->cbdata);
return TRUE;
}
/* exit otherwise */
if(0 >= data->timer)
if(0 < data->timer)
g_source_remove(data->timer);
data->timer = -1;
stoptransmission(data->cbdata);
gtk_widget_destroy(GTK_WIDGET(data->cbdata->wind));
if(NULL != data->cbdata->stupidpopuphack)
gtk_widget_destroy(data->cbdata->stupidpopuphack);
g_free(data->cbdata->buttons);
g_free(data->cbdata);
quittransmission(data->cbdata);
g_free(data);
gtk_main_quit();
return FALSE;
}
void
stoptransmission(struct cbdata *data) {
GtkTreeIter iter;
TrTorrent *tor;
gboolean go;
go = gtk_tree_model_get_iter_first(data->model, &iter);
while(go) {
gtk_tree_model_get(data->model, &iter, MC_TORRENT, &tor, -1);
go = gtk_list_store_remove(GTK_LIST_STORE(data->model), &iter);
g_object_unref(G_OBJECT(tor));
}
g_assert(0 == tr_torrentCount(tr_backend_handle(data->back)));
g_object_unref(G_OBJECT(data->back));
}
void
gotdrag(GtkWidget *widget SHUTUP, GdkDragContext *dc, gint x SHUTUP,
gint y SHUTUP, GtkSelectionData *sel, guint info SHUTUP, guint time,
@ -695,7 +663,7 @@ dfname(GtkTreeViewColumn *col SHUTUP, GtkCellRenderer *rend,
top = g_strdup_printf(_("Stopped (%.1f%%)"), prog);
else {
top = g_strdup("");
assert("XXX unknown status");
g_assert_not_reached();
}
if(TR_NOERROR != err) {
@ -762,9 +730,8 @@ updatemodel(gpointer gdata) {
char *upstr, *downstr, *str;
if(0 < global_sigcount) {
stoptransmission(data);
global_sigcount = SIGCOUNT_MAX;
raise(global_lastsig);
quittransmission(data);
return FALSE;
}
if(gtk_tree_model_get_iter_first(data->model, &iter)) {
@ -928,18 +895,19 @@ actionclick(GtkWidget *widget, gpointer gdata) {
for(info.off = 0; info.off < ALEN(actionitems); info.off++)
if(actionitems[info.off].act == info.act)
break;
assert(info.off < ALEN(actionitems));
g_assert(info.off < ALEN(actionitems));
gtk_tree_selection_selected_foreach(sel, popupaction, &info);
for(ii = info.dead; NULL != ii; ii = ii->next) {
assert(gtk_tree_row_reference_valid(ii->data));
g_assert(gtk_tree_row_reference_valid(ii->data));
path = gtk_tree_row_reference_get_path(ii->data);
gtk_tree_selection_unselect_path(info.sel, path);
if(gtk_tree_model_get_iter(data->model, &iter, path))
gtk_list_store_remove(GTK_LIST_STORE(data->model), &iter);
else
assert(!"bad path");
else {
g_assert_not_reached();
}
gtk_tree_path_free(path);
gtk_tree_row_reference_free(ii->data);
}
@ -1141,8 +1109,6 @@ void
fatalsig(int sig) {
struct sigaction sa;
global_lastsig = sig;
if(SIGCOUNT_MAX <= ++global_sigcount) {
bzero(&sa, sizeof(sa));
sa.sa_handler = SIG_DFL;

View File

@ -135,8 +135,6 @@ tr_backend_dispose(GObject *obj) {
return;
self->disposed = TRUE;
fprintf(stderr, "back dispose %p\n", self);
if(NULL != self->torrents) {
for(ii = self->torrents; NULL != ii; ii = ii->next)
g_object_weak_unref(ii->data, tr_backend_torrent_finalized, self);
@ -153,8 +151,6 @@ tr_backend_finalize(GObject *obj) {
GObjectClass *parent = g_type_class_peek(g_type_parent(TR_BACKEND_TYPE));
TrBackend *self = (TrBackend *)obj;
fprintf(stderr, "back finalize %p\n", self);
if(NULL != self->handle)
tr_close(self->handle);
@ -236,3 +232,27 @@ tr_backend_torrent_finalized(gpointer gdata, GObject *tor) {
back->torrents = g_list_remove(back->torrents, tor);
}
void
tr_backend_stop_torrents(TrBackend *back) {
GList *ii;
TR_IS_BACKEND(back);
for(ii = back->torrents; NULL != ii; ii = ii->next)
if(TR_STATUS_ACTIVE & tr_torrent_stat(ii->data)->status)
tr_torrentStop(tr_torrent_handle(ii->data));
}
gboolean
tr_backend_torrents_stopped(TrBackend *back) {
GList *ii;
TR_IS_BACKEND(back);
for(ii = back->torrents; NULL != ii; ii = ii->next)
if(TR_STATUS_ACTIVE & tr_torrent_stat(ii->data)->status)
return FALSE;
return TRUE;
}

View File

@ -48,6 +48,12 @@ tr_backend_save_state(TrBackend *back, char **errstr);
GList *
tr_backend_load_state(TrBackend *back, benc_val_t *state, GList **errors);
void
tr_backend_stop_torrents(TrBackend *back);
gboolean
tr_backend_torrents_stopped(TrBackend *back);
#ifdef TR_WANT_BACKEND_PRIVATE
void
tr_backend_add_torrent(TrBackend *back, GObject *tor);

View File

@ -33,8 +33,6 @@ tr_torrent_class_init(gpointer g_class, gpointer g_class_data);
static void
tr_torrent_dispose(GObject *obj);
static void
tr_torrent_finalize(GObject *obj);
static void
tr_torrent_set_folder(TrTorrent *tor);
static gboolean
tr_torrent_paused(TrTorrent *tor);
@ -70,7 +68,6 @@ tr_torrent_class_init(gpointer g_class, gpointer g_class_data SHUTUP) {
gobject_class->set_property = tr_torrent_set_property;
gobject_class->get_property = tr_torrent_get_property;
gobject_class->dispose = tr_torrent_dispose;
gobject_class->finalize = tr_torrent_finalize;
pspec = g_param_spec_pointer("torrent-handle", "Torrent handle",
"Torrent handle from libtransmission",
@ -178,8 +175,6 @@ tr_torrent_dispose(GObject *obj) {
return;
self->disposed = TRUE;
fprintf(stderr, "tor dispose %p\n", self);
if(NULL != self->handle) {
if(!tr_torrent_paused(self))
tr_torrentStop(self->handle);
@ -196,17 +191,6 @@ tr_torrent_dispose(GObject *obj) {
parent->dispose(obj);
}
static void
tr_torrent_finalize(GObject *obj) {
GObjectClass *parent = g_type_class_peek(g_type_parent(TR_TORRENT_TYPE));
TrTorrent *self = (TrTorrent *)obj;
fprintf(stderr, "tor finalize %p\n", self);
/* Chain up to the parent class */
parent->finalize(obj);
}
tr_torrent_t *
tr_torrent_handle(TrTorrent *tor) {
TR_IS_TORRENT(tor);