chiark / gitweb /
job: job_uninstall()
authorMichal Schmidt <mschmidt@redhat.com>
Fri, 20 Apr 2012 08:21:37 +0000 (10:21 +0200)
committerMichal Schmidt <mschmidt@redhat.com>
Fri, 20 Apr 2012 15:12:27 +0000 (17:12 +0200)
Split the uninstallation of the job from job_free() into a separate function.
Adjust the callers.

job_free() now only works on unlinked and uninstalled jobs. This enforces clear
thinking about job lifetimes.

src/core/job.c
src/core/job.h
src/core/manager.c
src/core/unit.c

index 5ea717eae1e58b421f07fc8e905865c6d065f110..9199cf6a4b6a0e54041159ab8f472d707840a292 100644 (file)
@@ -55,22 +55,24 @@ Job* job_new(Manager *m, JobType type, Unit *unit) {
         return j;
 }
 
-void job_free(Job *j) {
-        assert(j);
-
+void job_uninstall(Job *j) {
+        assert(j->installed);
         /* Detach from next 'bigger' objects */
-        if (j->installed) {
-                bus_job_send_removed_signal(j);
 
-                if (j->unit->job == j) {
-                        j->unit->job = NULL;
-                        unit_add_to_gc_queue(j->unit);
-                }
+        bus_job_send_removed_signal(j);
 
-                hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
-                j->installed = false;
+        if (j->unit->job == j) {
+                j->unit->job = NULL;
+                unit_add_to_gc_queue(j->unit);
         }
 
+        hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
+        j->installed = false;
+}
+
+void job_free(Job *j) {
+        assert(j);
+        assert(!j->installed);
         assert(!j->transaction_prev);
         assert(!j->transaction_next);
         assert(!j->subject_list);
@@ -492,6 +494,7 @@ int job_finish_and_invalidate(Job *j, JobResult result) {
 
         u = j->unit;
         t = j->type;
+        job_uninstall(j);
         job_free(j);
 
         job_print_status_message(u, t, result);
index 3ce2d65a0d96805027569bdac7cb84d8f0e579cd..442b13ef24d80e0d9ac8fecdbd1e467facd019c3 100644 (file)
@@ -137,6 +137,7 @@ struct Job {
 };
 
 Job* job_new(Manager *m, JobType type, Unit *unit);
+void job_uninstall(Job *j);
 void job_free(Job *job);
 void job_dump(Job *j, FILE*f, const char *prefix);
 
index 546b3233b0db522bcb69199026525cb06e9112c6..445931cb83c9b9a0884d2f80df9f2a7a5e7eb64d 100644 (file)
@@ -1275,13 +1275,17 @@ static int transaction_apply(Manager *m, JobMode mode) {
         }
 
         while ((j = hashmap_steal_first(m->transaction_jobs))) {
+                Job *uj;
                 if (j->installed) {
                         /* log_debug("Skipping already installed job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id); */
                         continue;
                 }
 
-                if (j->unit->job)
-                        job_free(j->unit->job);
+                uj = j->unit->job;
+                if (uj) {
+                        job_uninstall(uj);
+                        job_free(uj);
+                }
 
                 j->unit->job = j;
                 j->installed = true;
index df79fe3a69f62517c4967bf83a156d9254674721..ed3f176393f1120aca47bd03335a71237c05a8bf 100644 (file)
@@ -352,8 +352,11 @@ void unit_free(Unit *u) {
         SET_FOREACH(t, u->names, i)
                 hashmap_remove_value(u->manager->units, t, u);
 
-        if (u->job)
-                job_free(u->job);
+        if (u->job) {
+                Job *j = u->job;
+                job_uninstall(j);
+                job_free(j);
+        }
 
         for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
                 bidi_set_free(u, u->dependencies[d]);