chiark / gitweb /
job: separate job_install()
[elogind.git] / src / core / job.c
index f3c76d66b59dd85f1acd7948ca290c8ef7c9d0d3..0b5088818408092ce3b9f95dfffb4e132893178e 100644 (file)
 #include "log.h"
 #include "dbus-job.h"
 
-Job* job_new(Manager *m, JobType type, Unit *unit) {
+Job* job_new(Unit *unit, JobType type) {
         Job *j;
 
-        assert(m);
         assert(type < _JOB_TYPE_MAX);
         assert(unit);
 
         if (!(j = new0(Job, 1)))
                 return NULL;
 
-        j->manager = m;
-        j->id = m->current_job_id++;
+        j->manager = unit->manager;
+        j->id = j->manager->current_job_id++;
         j->type = type;
         j->unit = unit;
 
@@ -57,22 +56,11 @@ Job* job_new(Manager *m, JobType type, Unit *unit) {
 
 void job_free(Job *j) {
         assert(j);
-
-        /* 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);
-                }
-
-                hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
-                j->installed = false;
-        }
-
-        /* Detach from next 'smaller' objects */
-        manager_transaction_unlink_job(j->manager, j, true);
+        assert(!j->installed);
+        assert(!j->transaction_prev);
+        assert(!j->transaction_next);
+        assert(!j->subject_list);
+        assert(!j->object_list);
 
         if (j->in_run_queue)
                 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
@@ -93,6 +81,35 @@ void job_free(Job *j) {
         free(j);
 }
 
+void job_uninstall(Job *j) {
+        assert(j->installed);
+        /* Detach from next 'bigger' objects */
+
+        bus_job_send_removed_signal(j);
+
+        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_install(Job *j) {
+        Job *uj = j->unit->job;
+
+        if (uj) {
+                job_uninstall(uj);
+                job_free(uj);
+        }
+
+        j->unit->job = j;
+        j->installed = true;
+        j->manager->n_installed_jobs ++;
+        log_debug("Installed new job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
+}
+
 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
         JobDependency *l;
 
@@ -113,8 +130,6 @@ JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool
 
         if (subject)
                 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
-        else
-                LIST_PREPEND(JobDependency, subject, object->manager->transaction_anchor, l);
 
         LIST_PREPEND(JobDependency, object, object->object_list, l);
 
@@ -126,8 +141,6 @@ void job_dependency_free(JobDependency *l) {
 
         if (l->subject)
                 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
-        else
-                LIST_REMOVE(JobDependency, subject, l->object->manager->transaction_anchor, l);
 
         LIST_REMOVE(JobDependency, object, l->object->object_list, l);
 
@@ -152,18 +165,6 @@ void job_dump(Job *j, FILE*f, const char *prefix) {
                 prefix, yes_no(j->override));
 }
 
-bool job_is_anchor(Job *j) {
-        JobDependency *l;
-
-        assert(j);
-
-        LIST_FOREACH(object, l, j->object_list)
-                if (!l->subject)
-                        return true;
-
-        return false;
-}
-
 /*
  * Merging is commutative, so imagine the matrix as symmetric. We store only
  * its lower triangle to avoid duplication. We don't store the main diagonal,
@@ -490,6 +491,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);