Reap completed job threads only after every logical demand subscription and * watcher callback storage waiter has released the job. Exactly one caller * removes a job under the mutex. */
| 533 | * watcher callback storage waiter has released the job. Exactly one caller |
| 534 | * removes a job under the mutex. */ |
| 535 | static void application_jobs_reap_completed(cbm_daemon_application_t *application) { |
| 536 | for (;;) { |
| 537 | cbm_daemon_application_job_t *reap = NULL; |
| 538 | cbm_mutex_lock(&application->mutex); |
| 539 | cbm_daemon_application_job_t **cursor = &application->jobs; |
| 540 | while (*cursor) { |
| 541 | if ((*cursor)->thread_done && (*cursor)->subscribers == 0 && |
| 542 | (*cursor)->watcher_waiters == 0) { |
| 543 | reap = *cursor; |
| 544 | *cursor = reap->next; |
| 545 | reap->next = NULL; |
| 546 | break; |
| 547 | } |
| 548 | cursor = &(*cursor)->next; |
| 549 | } |
| 550 | cbm_mutex_unlock(&application->mutex); |
| 551 | if (!reap) { |
| 552 | return; |
| 553 | } |
| 554 | if (reap->thread_started) { |
| 555 | (void)cbm_thread_join(&reap->thread); |
| 556 | } |
| 557 | application_job_free(reap); |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | typedef enum { |
| 562 | APPLICATION_ATTEMPT_TERMINAL = 0, |
no test coverage detected