Changeset be07995 in mainline for uspace/srv/sysman/job_closure.c
- Timestamp:
- 2019-08-17T13:54:09Z (5 years ago)
- Children:
- 8d74fdd
- Parents:
- 015b147
- git-author:
- Michal Koutný <xm.koutny+hos@…> (2016-01-10 23:36:33)
- git-committer:
- Matthieu Riolo <matthieu.riolo@…> (2019-08-17 13:54:09)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/sysman/job_closure.c
r015b147 rbe07995 82 82 /** During visit creates job and appends it to closure 83 83 * 84 * @note Assumes BFS start unit's job is already present in closure! 84 * @note Assumes BFS origin unit's job is already present in the closure on the 85 * last position! 85 86 * 86 87 * @return EOK on success … … 94 95 95 96 if (e == NULL) { 96 assert(u->bfs_data == NULL); 97 if (u->bfs_data != NULL) { 98 goto finish; 99 } 97 100 job_t *first_job = dyn_array_last(closure, job_t *); 98 101 … … 133 136 job_del_ref(&created_job); 134 137 } 138 return rc; 139 } 140 141 static int visit_isolate(unit_t *u, unit_edge_t *e, bfs_ops_t *ops, void *arg) 142 { 143 int rc = EOK; 144 job_t *created_job = NULL; 145 job_closure_t *closure = arg; 146 147 sysman_log(LVL_DEBUG2, "%s(%s)", __func__, unit_name(u)); 148 /* 149 * Unit can have starting job from original request or from isolation 150 * BFS with different origin. 151 * 152 * Don't check u->state == STATE_STOPPED, closure is created stateless 153 * and its upon merging procedure to correctly resolve conflicting 154 * jobs. 155 * 156 * If we're at the origin (no BFS incoming edge), create a stop job, 157 * put it to the closure and let propagate as if called the propagate 158 * visitor. 159 */ 160 if (e == NULL && u->bfs_data == NULL) { 161 created_job = job_create(u, STATE_STOPPED); 162 if (created_job == NULL) { 163 rc = ENOMEM; 164 goto finish; 165 } 166 167 /* Pass job reference to closure and add one for unit */ 168 rc = dyn_array_append(closure, job_t *, created_job); 169 if (rc != EOK) { 170 goto finish; 171 } 172 } 173 rc = visit_propagate_job(u, e, ops, closure); 174 175 finish: 176 if (rc != EOK) { 177 job_del_ref(&created_job); 178 } 179 sysman_log(LVL_DEBUG2, "%s(%s) -> %i", __func__, unit_name(u), rc); 135 180 return rc; 136 181 } … … 217 262 } 218 263 219 // TODO bfs_traverse_all 220 264 static int bfs_traverse_all(bfs_ops_t *ops, void *arg) 265 { 266 /* Check invariant */ 267 repo_foreach(u) { 268 assert(u->bfs_tag == false); 269 } 270 int rc = EOK; 271 272 repo_foreach(origin) { 273 sysman_log(LVL_DEBUG2, "%s: %p, %i", __func__, origin, origin->bfs_tag); 274 if (origin->bfs_tag == true) { 275 continue; 276 } 277 rc = bfs_traverse_component_internal(origin, ops, arg); 278 if (rc != EOK) { 279 goto finish; 280 } 281 } 282 283 finish: 284 /* Clean after ourselves (BFS tag jobs) */ 285 repo_foreach(u) { 286 u->bfs_tag = false; 287 } 288 return rc; 289 } 221 290 222 291 /* … … 230 299 * @return EOK on success otherwise propagated error 231 300 */ 232 int job_create_closure(job_t *main_job, job_closure_t *job_closure )301 int job_create_closure(job_t *main_job, job_closure_t *job_closure, int flags) 233 302 { 234 303 sysman_log(LVL_DEBUG2, "%s(%s)", __func__, unit_name(main_job->unit)); 235 304 236 static bfs_ops_t ops = { 305 if ((flags & CLOSURE_ISOLATE) && main_job->target_state != STATE_STARTED) { 306 // TODO EINVAL? 307 return ENOTSUP; 308 } 309 310 int rc = dyn_array_append(job_closure, job_t *, main_job); 311 if (rc != EOK) { 312 return rc; 313 } 314 job_add_ref(main_job); /* Add one for the closure */ 315 316 /* Propagate main_job to other (dependent) units */ 317 static bfs_ops_t propagate_ops = { 237 318 .clean = traverse_clean, 238 319 .visit = visit_propagate_job 239 320 }; 240 241 321 switch (main_job->target_state) { 242 322 case STATE_STARTED: 243 ops.direction = BFS_FORWARD;323 propagate_ops.direction = BFS_FORWARD; 244 324 break; 245 325 case STATE_STOPPED: 246 ops.direction = BFS_BACKWARD;326 propagate_ops.direction = BFS_BACKWARD; 247 327 break; 248 328 default: … … 250 330 } 251 331 252 int rc = dyn_array_append(job_closure, job_t *, main_job); 253 if (rc != EOK) { 254 return rc; 255 } 256 job_add_ref(main_job); /* Add one for the closure */ 257 258 rc = bfs_traverse_component(main_job->unit, &ops, job_closure); 332 rc = bfs_traverse_component(main_job->unit, &propagate_ops, job_closure); 333 334 sysman_log(LVL_DEBUG2, "%s: %i&%i", __func__, flags, CLOSURE_ISOLATE); 335 if (flags & CLOSURE_ISOLATE) { 336 static bfs_ops_t isolate_ops = { 337 .direction = BFS_BACKWARD, 338 .clean = traverse_clean, 339 .visit = visit_isolate 340 }; 341 rc = bfs_traverse_all(&isolate_ops, job_closure); 342 } 259 343 260 344 if (rc == EOK) { 261 sysman_log(LVL_DEBUG2, "%s(%s):", __func__, unit_name(main_job->unit));262 345 dyn_array_foreach(*job_closure, job_t *, job_it) { 263 346 sysman_log(LVL_DEBUG2, "%s\t%s, refs: %u", __func__,
Note:
See TracChangeset
for help on using the changeset viewer.