struct reaper {
struct lightrec_state *state;
pthread_mutex_t mutex;
+ pthread_cond_t cond;
struct slist_elm reap_list;
+ bool running;
atomic_uint sem;
};
}
reaper->state = state;
+ reaper->running = false;
reaper->sem = 0;
slist_init(&reaper->reap_list);
ret = pthread_mutex_init(&reaper->mutex, NULL);
if (ret) {
pr_err("Cannot init mutex variable: %d\n", ret);
- lightrec_free(reaper->state, MEM_FOR_LIGHTREC,
- sizeof(*reaper), reaper);
- return NULL;
+ goto err_free_reaper;
+ }
+
+ ret = pthread_cond_init(&reaper->cond, NULL);
+ if (ret) {
+ pr_err("Cannot init cond variable: %d\n", ret);
+ goto err_destroy_mutex;
}
return reaper;
+
+err_destroy_mutex:
+ pthread_mutex_destroy(&reaper->mutex);
+err_free_reaper:
+ lightrec_free(reaper->state, MEM_FOR_LIGHTREC, sizeof(*reaper), reaper);
+ return NULL;
}
void lightrec_reaper_destroy(struct reaper *reaper)
{
+ lightrec_reaper_reap(reaper);
+
+ pthread_cond_destroy(&reaper->cond);
pthread_mutex_destroy(&reaper->mutex);
lightrec_free(reaper->state, MEM_FOR_LIGHTREC, sizeof(*reaper), reaper);
}
while (lightrec_reaper_can_reap(reaper) &&
!!(elm = slist_first(&reaper->reap_list))) {
slist_remove(&reaper->reap_list, elm);
+ reaper->running = true;
pthread_mutex_unlock(&reaper->mutex);
reaper_elm = container_of(elm, struct reaper_elm, slist);
sizeof(*reaper_elm), reaper_elm);
pthread_mutex_lock(&reaper->mutex);
+ reaper->running = false;
+ pthread_cond_broadcast(&reaper->cond);
}
pthread_mutex_unlock(&reaper->mutex);
void lightrec_reaper_pause(struct reaper *reaper)
{
atomic_fetch_add_explicit(&reaper->sem, 1, memory_order_relaxed);
+
+ pthread_mutex_lock(&reaper->mutex);
+ while (reaper->running)
+ pthread_cond_wait(&reaper->cond, &reaper->mutex);
+ pthread_mutex_unlock(&reaper->mutex);
}
void lightrec_reaper_continue(struct reaper *reaper)