Changeset 8432ae1 in mainline for uspace/srv/sysman/job.c
- Timestamp:
- 2019-08-03T08:33:31Z (6 years ago)
- Children:
- 4b1c6a4b
- Parents:
- 095d03c
- git-author:
- Michal Koutny <xm.koutny+hos@…> (2015-04-25 00:29:51)
- git-committer:
- Matthieu Riolo <matthieu.riolo@…> (2019-08-03 08:33:31)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/sysman/job.c
r095d03c r8432ae1 48 48 return ENOMEM; 49 49 } 50 51 50 job_add_ref(blocked_job); 51 52 52 blocked_job->blocking_jobs += 1; 53 53 54 54 return EOK; 55 } 56 57 /** Remove blocking_job from blocked job structure 58 * 59 * @note Caller must remove blocked_job from collection of blocked_jobs 60 */ 61 static void job_unblock(job_t *blocked_job, job_t *blocking_job) 62 { 63 if (blocking_job->retval == JOB_FAILED) { 64 blocked_job->blocking_job_failed = true; 65 } 66 blocked_job->blocking_jobs -= 1; 67 68 job_del_ref(&blocked_job); 55 69 } 56 70 … … 62 76 link_initialize(&job->job_queue); 63 77 64 /* Start with one reference for the creator */ 65 atomic_set(&job->refcnt, 1); 78 atomic_set(&job->refcnt, 0); 66 79 67 80 job->target_state = target_state; … … 100 113 job_t *job = data; 101 114 115 /* 116 * We have one reference from caller for our disposal, * 117 * if needed, pass it to observer. 118 */ 102 119 if (job_eval_retval(job)) { 103 120 job_finish(job); 121 job_del_ref(&job); 104 122 } else { 105 123 // TODO place for timeout 106 // TODO add reference to job?107 124 sysman_object_observer(u, &job_check, job); 108 125 } … … 110 127 111 128 112 static void job_unblock(job_t *blocked_job, job_t *blocking_job) 113 { 114 if (blocking_job->retval == JOB_FAILED) { 115 blocked_job->blocking_job_failed = true; 116 } 117 blocked_job->blocking_jobs -= 1; 118 } 129 119 130 120 131 static void job_destroy(job_t **job_ptr) … … 126 137 127 138 assert(!link_used(&job->job_queue)); 139 140 dyn_array_foreach(job->blocked_jobs, job_ptr_t, job_it) { 141 job_del_ref(&(*job_it)); 142 } 128 143 dyn_array_destroy(&job->blocked_jobs); 129 // TODO I should decrease referece of blocked jobs130 144 131 145 free(job); … … 164 178 (*job_it)->state = JOB_QUEUED; 165 179 list_append(&(*job_it)->job_queue, &job_queue); 166 // TODO explain this reference 167 job_add_ref(*job_it); 180 /* We pass reference from the closure to the queue */ 168 181 } 169 182 … … 203 216 204 217 if (result) { 205 / / TODO update refcount218 /* Remove job from queue and pass refernce to caller */ 206 219 list_remove(&result->job_queue); 207 220 result->state = JOB_DEQUEUED; … … 225 238 * Traverse dependency graph in BFS fashion and create jobs for every 226 239 * necessary unit. 240 * Closure keeps reference to each job. We've to add reference to the 241 * main job, other newly created jobs are pased to the closure. 227 242 */ 228 243 fifo_push(jobs_fifo, main_job); 229 244 job_t *job; 245 job_add_ref(main_job); 230 246 while ((job = fifo_pop(jobs_fifo)) != NULL) { 231 /* 232 * Do not increase reference count of job, as we're passing it 233 * to the closure. 234 */ 247 /* No refcount increase, pass it to the closure */ 235 248 dyn_array_append(job_closure, job_ptr_t, job); 236 249 … … 256 269 /* 257 270 * Newly created jobs are already passed to the closure, thus not 258 * deleting them here.271 * deleting reference to them here. 259 272 */ 260 273 return rc; … … 266 279 if (job != NULL) { 267 280 job_init(job, u, target_state); 281 282 /* Start with one reference for the creator */ 283 job_add_ref(job); 268 284 } 269 285 … … 271 287 } 272 288 289 /** Add one reference to job 290 * 291 * Usage: 292 * - adding observer which references the job, 293 * - raising and event that references the job, 294 * - anytime any other new reference is made. 295 */ 273 296 void job_add_ref(job_t *job) 274 297 { … … 276 299 } 277 300 301 /** Remove one reference from job, last remover destroys the job 302 * 303 * Usage: 304 * - inside observer callback that references the job, 305 * - inside event handler that references the job, 306 * - anytime you dispose a reference to the job. 307 */ 278 308 void job_del_ref(job_t **job_ptr) 279 309 { 280 310 job_t *job = *job_ptr; 281 if (job == NULL) { 282 return; 283 } 284 311 312 assert(job != NULL); 285 313 assert(atomic_get(&job->refcnt) > 0); 286 314 if (atomic_predec(&job->refcnt) == 0) { … … 295 323 296 324 unit_t *u = job->unit; 297 sysman_log(LVL_DEBUG, "%s , %s -> %i",298 __func__, unit_name(u), job->target_state);325 sysman_log(LVL_DEBUG, "%s(%p), %s -> %i", 326 __func__, job, unit_name(u), job->target_state); 299 327 300 328 /* Propagate failure */ … … 316 344 } 317 345 346 /* 347 * job_check deletes reference, we want job to remain to caller, thus 348 * add one dummy ref 349 */ 350 job_add_ref(job); 318 351 job_check(job->unit, job); 319 352 return; … … 333 366 assert(job->retval != JOB_UNDEFINED_); 334 367 335 sysman_log(LVL_DEBUG2, "%s(% s)-> %i",336 __func__, unit_name(job->unit), job->retval);368 sysman_log(LVL_DEBUG2, "%s(%p) %s -> %i", 369 __func__, job, unit_name(job->unit), job->retval); 337 370 338 371 job->state = JOB_FINISHED; 339 372 340 /* Job finished*/373 /* First remove references, then clear the array */ 341 374 dyn_array_foreach(job->blocked_jobs, job_ptr_t, job_it) { 342 375 job_unblock(*job_it, job); 343 376 } 344 // TODO remove reference from blocked jobs 345 346 // TODO should reference be added (for the created event) 377 dyn_array_clear(&job->blocked_jobs); 378 379 /* Add reference for the event */ 380 job_add_ref(job); 347 381 sysman_raise_event(&sysman_event_job_changed, job); 348 382 }
Note:
See TracChangeset
for help on using the changeset viewer.