+// SPDX-License-Identifier: LGPL-2.1-or-later
/*
- * Copyright (C) 2020 Paul Cercueil <paul@crapouillou.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
+ * Copyright (C) 2020-2021 Paul Cercueil <paul@crapouillou.net>
*/
#include "blockcache.h"
#include <errno.h>
#include <pthread.h>
+#include <stdatomic.h>
#include <stdbool.h>
struct reaper_elm {
struct lightrec_state *state;
pthread_mutex_t mutex;
struct slist_elm reap_list;
+
+ atomic_uint sem;
};
struct reaper *lightrec_reaper_init(struct lightrec_state *state)
}
reaper->state = state;
+ reaper->sem = 0;
slist_init(&reaper->reap_list);
ret = pthread_mutex_init(&reaper->mutex, NULL);
return ret;
}
+static bool lightrec_reaper_can_reap(struct reaper *reaper)
+{
+ return !atomic_load_explicit(&reaper->sem, memory_order_relaxed);
+}
+
void lightrec_reaper_reap(struct reaper *reaper)
{
struct reaper_elm *reaper_elm;
pthread_mutex_lock(&reaper->mutex);
- while (!!(elm = slist_first(&reaper->reap_list))) {
+ while (lightrec_reaper_can_reap(reaper) &&
+ !!(elm = slist_first(&reaper->reap_list))) {
slist_remove(&reaper->reap_list, elm);
pthread_mutex_unlock(&reaper->mutex);
reaper_elm = container_of(elm, struct reaper_elm, slist);
- (*reaper_elm->func)(reaper_elm->data);
+ (*reaper_elm->func)(reaper->state, reaper_elm->data);
lightrec_free(reaper->state, MEM_FOR_LIGHTREC,
sizeof(*reaper_elm), reaper_elm);
pthread_mutex_unlock(&reaper->mutex);
}
+
+void lightrec_reaper_pause(struct reaper *reaper)
+{
+ atomic_fetch_add_explicit(&reaper->sem, 1, memory_order_relaxed);
+}
+
+void lightrec_reaper_continue(struct reaper *reaper)
+{
+ atomic_fetch_sub_explicit(&reaper->sem, 1, memory_order_relaxed);
+}