-/*-*- Mode: C; c-basic-offset: 8 -*-*/
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
free(l);
}
-void job_dependency_delete(Job *subject, Job *object, bool *matters) {
- JobDependency *l;
-
- assert(object);
-
- LIST_FOREACH(object, l, object->object_list) {
- assert(l->object == object);
-
- if (l->subject == subject)
- break;
- }
-
- if (!l) {
- if (matters)
- *matters = false;
- return;
- }
-
- if (matters)
- *matters = l->matters;
-
- job_dependency_free(l);
-}
-
void job_dump(Job *j, FILE*f, const char *prefix) {
assert(j);
assert(f);
int job_run_and_invalidate(Job *j) {
int r;
+ uint32_t id;
+ Manager *m;
assert(j);
assert(j->installed);
j->state = JOB_RUNNING;
job_add_to_dbus_queue(j);
+ /* While we execute this operation the job might go away (for
+ * example: because it is replaced by a new, conflicting
+ * job.) To make sure we don't access a freed job later on we
+ * store the id here, so that we can verify the job is still
+ * valid. */
+ id = j->id;
+ m = j->manager;
+
switch (j->type) {
case JOB_START:
assert_not_reached("Unknown job type");
}
- if (r == -EALREADY)
- r = job_finish_and_invalidate(j, true);
- else if (r == -EAGAIN) {
- j->state = JOB_WAITING;
- return -EAGAIN;
- } else if (r < 0)
- r = job_finish_and_invalidate(j, false);
+ if ((j = manager_get_job(m, id))) {
+ if (r == -EALREADY)
+ r = job_finish_and_invalidate(j, true);
+ else if (r == -EAGAIN)
+ j->state = JOB_WAITING;
+ else if (r < 0)
+ r = job_finish_and_invalidate(j, false);
+ }
return r;
}