]>
Commit | Line | Data |
---|---|---|
60918275 LP |
1 | /*-*- Mode: C; c-basic-offset: 8 -*-*/ |
2 | ||
3 | #include <assert.h> | |
4 | ||
5 | #include "macro.h" | |
6 | #include "job.h" | |
7 | ||
8 | Job* job_new(Manager *m, JobType type, Name *name) { | |
9 | Job *j; | |
10 | ||
11 | assert(m); | |
12 | assert(type < _JOB_TYPE_MAX); | |
13 | assert(name); | |
14 | ||
15 | if (!(j = new0(Job, 1))) | |
16 | return NULL; | |
17 | ||
18 | j->manager = m; | |
19 | j->id = m->current_job_id++; | |
20 | j->type = type; | |
21 | j->name = name; | |
22 | ||
e5b5ae50 | 23 | /* We don't link it here, that's what job_dependency() is for */ |
60918275 LP |
24 | |
25 | return j; | |
26 | } | |
27 | ||
60918275 LP |
28 | void job_free(Job *j) { |
29 | assert(j); | |
30 | ||
31 | /* Detach from next 'bigger' objects */ | |
32 | ||
33 | if (j->linked) { | |
11dd41ce LP |
34 | if (j->name->meta.job == j) |
35 | j->name->meta.job = NULL; | |
60918275 LP |
36 | |
37 | hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id)); | |
38 | } | |
39 | ||
e5b5ae50 | 40 | manager_transaction_delete_job(j->manager, j); |
60918275 LP |
41 | |
42 | free(j); | |
43 | } | |
a66d02c3 | 44 | |
e5b5ae50 LP |
45 | JobDependency* job_dependency_new(Job *subject, Job *object, bool matters) { |
46 | JobDependency *l; | |
47 | ||
48 | assert(object); | |
49 | ||
50 | /* Adds a new job link, which encodes that the 'subject' job | |
51 | * needs the 'object' job in some way. If 'subject' is NULL | |
52 | * this means the 'anchor' job (i.e. the one the user | |
53 | * explcitily asked for) is the requester. */ | |
54 | ||
ceed3570 | 55 | if (!(l = new0(JobDependency, 1))) |
e5b5ae50 LP |
56 | return NULL; |
57 | ||
58 | l->subject = subject; | |
59 | l->object = object; | |
60 | l->matters = matters; | |
61 | ||
62 | if (subject) { | |
63 | l->subject_next = subject->subject_list; | |
64 | subject->subject_list = l; | |
65 | } else { | |
66 | l->subject_next = object->manager->transaction_anchor; | |
67 | object->manager->transaction_anchor = l; | |
68 | } | |
69 | ||
70 | if (l->subject_next) | |
71 | l->subject_next->subject_prev = l; | |
72 | l->subject_prev = NULL; | |
73 | ||
74 | if ((l->object_next = object->object_list)) | |
75 | l->object_next->object_prev = l; | |
76 | l->object_prev = NULL; | |
77 | object->object_list = l; | |
78 | ||
79 | return l; | |
80 | } | |
81 | ||
82 | void job_dependency_free(JobDependency *l) { | |
83 | assert(l); | |
84 | ||
85 | if (l->subject_prev) | |
86 | l->subject_prev->subject_next = l->subject_next; | |
87 | else if (l->subject) | |
88 | l->subject->subject_list = l->subject_next; | |
89 | else | |
90 | l->object->manager->transaction_anchor = l->subject_next; | |
91 | ||
92 | if (l->subject_next) | |
93 | l->subject_next->subject_prev = l->subject_prev; | |
94 | ||
95 | if (l->object_prev) | |
96 | l->object_prev->object_next = l->object_next; | |
97 | else | |
98 | l->object->object_list = l->object_next; | |
99 | ||
100 | if (l->object_next) | |
101 | l->object_next->object_prev = l->object_prev; | |
102 | ||
103 | free(l); | |
104 | } | |
105 | ||
106 | void job_dependency_delete(Job *subject, Job *object, bool *matters) { | |
107 | JobDependency *l; | |
108 | ||
109 | assert(object); | |
110 | ||
111 | for (l = object->object_list; l; l = l->object_next) { | |
112 | assert(l->object == object); | |
113 | ||
114 | if (l->subject == subject) | |
115 | break; | |
116 | } | |
117 | ||
118 | if (!l) { | |
119 | if (matters) | |
120 | *matters = false; | |
121 | return; | |
122 | } | |
123 | ||
124 | if (matters) | |
125 | *matters = l->matters; | |
126 | ||
127 | job_dependency_free(l); | |
128 | } | |
129 | ||
ceed3570 | 130 | void job_dump(Job *j, FILE*f, const char *prefix) { |
a66d02c3 LP |
131 | |
132 | static const char* const job_type_table[_JOB_TYPE_MAX] = { | |
42f4e3c4 LP |
133 | [JOB_START] = "start", |
134 | [JOB_STOP] = "stop", | |
135 | [JOB_VERIFY_STARTED] = "verify-started", | |
136 | [JOB_RELOAD] = "reload", | |
e5b5ae50 | 137 | [JOB_RELOAD_OR_START] = "reload-or-start", |
42f4e3c4 LP |
138 | [JOB_RESTART] = "restart", |
139 | [JOB_TRY_RESTART] = "try-restart", | |
a66d02c3 LP |
140 | }; |
141 | ||
142 | static const char* const job_state_table[_JOB_STATE_MAX] = { | |
42f4e3c4 LP |
143 | [JOB_WAITING] = "waiting", |
144 | [JOB_RUNNING] = "running", | |
145 | [JOB_DONE] = "done" | |
a66d02c3 LP |
146 | }; |
147 | ||
148 | assert(j); | |
149 | assert(f); | |
150 | ||
ceed3570 LP |
151 | fprintf(f, |
152 | "%sJob %u:\n" | |
153 | "%s\tAction: %s → %s\n" | |
154 | "%s\tState: %s\n", | |
155 | prefix, j->id, | |
156 | prefix, name_id(j->name), job_type_table[j->type], | |
157 | prefix, job_state_table[j->state]); | |
a66d02c3 | 158 | } |
e5b5ae50 LP |
159 | |
160 | bool job_is_anchor(Job *j) { | |
161 | JobDependency *l; | |
162 | ||
163 | assert(j); | |
164 | ||
165 | for (l = j->object_list; l; l = l->object_next) | |
166 | if (!l->subject) | |
167 | return true; | |
168 | ||
169 | return false; | |
170 | } |