From 2ad4fbb34ae9110477be484f24c162bc5687253b Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 10 Oct 2011 15:30:07 +0100 Subject: [PATCH] startup: delete the startup sequence upon completion, make the timeout complete it --- include/data.h | 5 +++++ src/startup.c | 25 ++++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/include/data.h b/include/data.h index ba836d55..60e1ef26 100644 --- a/include/data.h +++ b/include/data.h @@ -11,6 +11,9 @@ #ifndef _DATA_H #define _DATA_H +#define SN_API_NOT_YET_FROZEN 1 +#include + #include #include #include @@ -150,6 +153,8 @@ struct Startup_Sequence { char *id; /** workspace on which this startup was initiated */ char *workspace; + /** libstartup-notification context for this launch */ + SnLauncherContext *context; TAILQ_ENTRY(Startup_Sequence) sequences; }; diff --git a/src/startup.c b/src/startup.c index 1a584cd4..4b6c937d 100644 --- a/src/startup.c +++ b/src/startup.c @@ -24,8 +24,8 @@ static TAILQ_HEAD(startup_sequence_head, Startup_Sequence) startup_sequences = /* * After 60 seconds, a timeout will be triggered for each startup sequence. * - * The internal startup sequence will be deleted, the libstartup-notification - * context will be completed and unref'd (therefore free'd aswell). + * The timeout will just trigger completion of the sequence, so the normal + * completion process takes place (startup_monitor_event will free it). * */ static void startup_timeout(EV_P_ ev_timer *w, int revents) { @@ -41,17 +41,16 @@ static void startup_timeout(EV_P_ ev_timer *w, int revents) { break; } + /* Unref the context (for the timeout itself, see start_application) */ + sn_launcher_context_unref(w->data); + if (!sequence) { DLOG("Sequence already deleted, nevermind.\n"); return; } - /* Delete our internal sequence */ - TAILQ_REMOVE(&startup_sequences, sequence, sequences); - - /* Complete and unref the context */ + /* Complete the startup sequence, will trigger its deletion. */ sn_launcher_context_complete(w->data); - sn_launcher_context_unref(w->data); free(w); } @@ -95,8 +94,14 @@ void start_application(const char *command) { struct Startup_Sequence *sequence = scalloc(sizeof(struct Startup_Sequence)); sequence->id = sstrdup(sn_launcher_context_get_startup_id(context)); sequence->workspace = sstrdup(ws->name); + sequence->context = context; TAILQ_INSERT_TAIL(&startup_sequences, sequence, sequences); + /* Increase the refcount once (it starts with 1, so it will be 2 now) for + * the timeout. Even if the sequence gets completed, the timeout still + * needs the context (but will unref it then) */ + sn_launcher_context_ref(context); + LOG("executing: %s\n", command); if (fork() == 0) { /* Child process */ @@ -149,6 +154,12 @@ void startup_monitor_event(SnMonitorEvent *event, void *userdata) { switch (sn_monitor_event_get_type(event)) { case SN_MONITOR_EVENT_COMPLETED: DLOG("startup sequence %s completed\n", sn_startup_sequence_get_id(snsequence)); + + /* Unref the context, will be free()d */ + sn_launcher_context_unref(sequence->context); + + /* Delete our internal sequence */ + TAILQ_REMOVE(&startup_sequences, sequence, sequences); break; default: /* ignore */