Remove rz_th_kill, rz_th_kill_free and rz_th_pool_kill (#2790)
This commit is contained in:
parent
906fe97252
commit
522ab57c75
9 changed files with 130 additions and 169 deletions
|
|
@ -26,6 +26,7 @@ typedef struct search_thread_data_t {
|
|||
RzStrEnc encoding;
|
||||
bool check_ascii_freq;
|
||||
SharedData *shared;
|
||||
RzAtomicBool *loop;
|
||||
} SearchThreadData;
|
||||
|
||||
static st64 shared_data_read_at(SharedData *sd, ut64 addr, ut8 *buf, ut64 size) {
|
||||
|
|
@ -122,7 +123,7 @@ static void *search_string_thread_runner(SearchThreadData *std) {
|
|||
RZ_LOG_DEBUG("[%p] searching between [0x%08" PFMT64x " : 0x%08" PFMT64x "]\n", std, paddr, paddr + psize);
|
||||
|
||||
RzList *list = string_scan_range(std, paddr, psize);
|
||||
while (list) {
|
||||
while (list && rz_atomic_bool_get(std->loop)) {
|
||||
detected = rz_list_pop_head(list);
|
||||
if (!detected) {
|
||||
break;
|
||||
|
|
@ -145,7 +146,7 @@ static void *search_string_thread_runner(SearchThreadData *std) {
|
|||
}
|
||||
|
||||
rz_list_free(list);
|
||||
} while (loop);
|
||||
} while (loop && rz_atomic_bool_get(std->loop));
|
||||
|
||||
RZ_LOG_DEBUG("[%p] died\n", std);
|
||||
return NULL;
|
||||
|
|
@ -156,9 +157,27 @@ static void bin_file_string_search_free(SearchThreadData *std) {
|
|||
return;
|
||||
}
|
||||
rz_list_free(std->results);
|
||||
rz_atomic_bool_free(std->loop);
|
||||
free(std);
|
||||
}
|
||||
|
||||
static void interrupt_thread(RzThread *thread) {
|
||||
if (!thread) {
|
||||
return;
|
||||
}
|
||||
SearchThreadData *std = (SearchThreadData *)rz_th_get_user(thread);
|
||||
rz_atomic_bool_set(std->loop, false);
|
||||
rz_th_wait(thread);
|
||||
}
|
||||
|
||||
static void interrupt_pool(RzThreadPool *pool) {
|
||||
size_t pool_size = rz_th_pool_size(pool);
|
||||
for (size_t i = 0; i < pool_size; ++i) {
|
||||
RzThread *th = rz_th_pool_get_thread(pool, i);
|
||||
interrupt_thread(th);
|
||||
}
|
||||
}
|
||||
|
||||
static bool create_string_search_thread(RzThreadPool *pool, size_t min_length, RzThreadQueue *intervals, SharedData *shared) {
|
||||
RzStrEnc encoding = RZ_STRING_ENC_GUESS;
|
||||
RzBinPlugin *plugin = rz_bin_file_cur_plugin(shared->bf);
|
||||
|
|
@ -189,6 +208,7 @@ static bool create_string_search_thread(RzThreadPool *pool, size_t min_length, R
|
|||
std->encoding = encoding;
|
||||
std->intervals = intervals;
|
||||
std->min_length = min_length;
|
||||
std->loop = rz_atomic_bool_new(true);
|
||||
|
||||
RzThread *thread = rz_th_new((RzThreadFunction)search_string_thread_runner, std);
|
||||
if (!thread) {
|
||||
|
|
@ -197,6 +217,7 @@ static bool create_string_search_thread(RzThreadPool *pool, size_t min_length, R
|
|||
return false;
|
||||
} else if (!rz_th_pool_add_thread(pool, thread)) {
|
||||
RZ_LOG_ERROR("bin_file_strings: cannot add thread to pool\n");
|
||||
interrupt_thread(thread);
|
||||
bin_file_string_search_free(std);
|
||||
rz_th_free(thread);
|
||||
return false;
|
||||
|
|
@ -430,7 +451,7 @@ RZ_API RZ_OWN RzList *rz_bin_file_strings(RZ_NONNULL RzBinFile *bf, size_t min_l
|
|||
RZ_LOG_VERBOSE("bin_file_strings: using %u threads\n", (ut32)pool_size);
|
||||
for (size_t i = 0; i < pool_size; ++i) {
|
||||
if (!create_string_search_thread(pool, min_length, intervals, &shared)) {
|
||||
rz_th_pool_kill(pool);
|
||||
interrupt_pool(pool);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,6 @@ typedef struct basefind_data_t {
|
|||
BaseFindArray *array;
|
||||
} BaseFindData;
|
||||
|
||||
typedef struct thread_bool_t {
|
||||
bool value;
|
||||
RzThreadLock *lock;
|
||||
} ThreadBool;
|
||||
|
||||
typedef struct basefind_thread_data_t {
|
||||
ut32 id;
|
||||
ut64 current;
|
||||
|
|
@ -40,38 +35,16 @@ typedef struct basefind_thread_data_t {
|
|||
RzList *scores;
|
||||
HtUU *pointers;
|
||||
BaseFindArray *array;
|
||||
ThreadBool loop;
|
||||
RzAtomicBool *loop;
|
||||
} BaseFindThreadData;
|
||||
|
||||
typedef struct basefind_ui_info_t {
|
||||
ThreadBool loop;
|
||||
RzAtomicBool *loop;
|
||||
RzThreadPool *pool;
|
||||
void *user;
|
||||
RzBaseFindThreadInfoCb callback;
|
||||
} BaseFindUIInfo;
|
||||
|
||||
static void thread_bool_init(ThreadBool *tl) {
|
||||
tl->lock = rz_th_lock_new(false);
|
||||
tl->value = true;
|
||||
}
|
||||
|
||||
static bool thread_bool_get(ThreadBool *tl) {
|
||||
rz_th_lock_enter(tl->lock);
|
||||
bool value = tl->value;
|
||||
rz_th_lock_leave(tl->lock);
|
||||
return value;
|
||||
}
|
||||
|
||||
static void thread_bool_set(ThreadBool *tl, bool value) {
|
||||
rz_th_lock_enter(tl->lock);
|
||||
tl->value = value;
|
||||
rz_th_lock_leave(tl->lock);
|
||||
}
|
||||
|
||||
static void thread_bool_fini(ThreadBool *tl) {
|
||||
rz_th_lock_free(tl->lock);
|
||||
}
|
||||
|
||||
static void basefind_stop_all_search_threads(RzThreadPool *pool) {
|
||||
size_t pool_size = rz_th_pool_size(pool);
|
||||
for (ut32 i = 0; i < pool_size; ++i) {
|
||||
|
|
@ -80,7 +53,7 @@ static void basefind_stop_all_search_threads(RzThreadPool *pool) {
|
|||
continue;
|
||||
}
|
||||
BaseFindThreadData *bftd = rz_th_get_user(th);
|
||||
thread_bool_set(&bftd->loop, false);
|
||||
rz_atomic_bool_set(bftd->loop, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,14 +215,14 @@ static int basefind_score_compare(const RzBaseFindScore *a, const RzBaseFindScor
|
|||
}
|
||||
|
||||
static void *basefind_thread_runner(BaseFindThreadData *bftd) {
|
||||
ThreadBool *loop = &bftd->loop;
|
||||
RzAtomicBool *loop = bftd->loop;
|
||||
RzBaseFindScore *pair = NULL;
|
||||
BaseFindData bfd;
|
||||
ut64 base;
|
||||
|
||||
bfd.array = bftd->array;
|
||||
for (base = bftd->base_start; base < bftd->base_end; base += bftd->alignment) {
|
||||
if (!thread_bool_get(loop)) {
|
||||
if (!rz_atomic_bool_get(loop)) {
|
||||
break;
|
||||
}
|
||||
bftd->current = base;
|
||||
|
|
@ -303,6 +276,7 @@ static void basefind_set_thread_info(BaseFindThreadData *bftd, RzBaseFindThreadI
|
|||
// data that will always be available during its lifetime.
|
||||
static void *basefind_thread_ui(BaseFindUIInfo *ui_info) {
|
||||
RzThreadPool *pool = ui_info->pool;
|
||||
RzAtomicBool *loop = ui_info->loop;
|
||||
ut32 pool_size = rz_th_pool_size(pool);
|
||||
RzBaseFindThreadInfoCb callback = ui_info->callback;
|
||||
void *user = ui_info->user;
|
||||
|
|
@ -323,7 +297,7 @@ static void *basefind_thread_ui(BaseFindUIInfo *ui_info) {
|
|||
}
|
||||
}
|
||||
rz_sys_usleep(100000);
|
||||
} while (thread_bool_get(&ui_info->loop));
|
||||
} while (rz_atomic_bool_get(loop));
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -450,7 +424,7 @@ RZ_API RZ_OWN RzList *rz_basefind(RZ_NONNULL RzCore *core, RZ_NONNULL RzBaseFind
|
|||
bftd->scores = scores;
|
||||
bftd->pointers = pointers;
|
||||
bftd->array = array;
|
||||
thread_bool_init(&bftd->loop);
|
||||
bftd->loop = rz_atomic_bool_new(true);
|
||||
if (!create_thread_interval(pool, bftd)) {
|
||||
free(bftd);
|
||||
basefind_stop_all_search_threads(pool);
|
||||
|
|
@ -462,7 +436,7 @@ RZ_API RZ_OWN RzList *rz_basefind(RZ_NONNULL RzCore *core, RZ_NONNULL RzBaseFind
|
|||
ui_info.pool = pool;
|
||||
ui_info.user = options->user;
|
||||
ui_info.callback = options->callback;
|
||||
thread_bool_init(&ui_info.loop);
|
||||
ui_info.loop = rz_atomic_bool_new(true);
|
||||
user_thread = rz_th_new((RzThreadFunction)basefind_thread_ui, &ui_info);
|
||||
if (!user_thread) {
|
||||
basefind_stop_all_search_threads(pool);
|
||||
|
|
@ -474,10 +448,10 @@ RZ_API RZ_OWN RzList *rz_basefind(RZ_NONNULL RzCore *core, RZ_NONNULL RzBaseFind
|
|||
rz_th_pool_wait(pool);
|
||||
|
||||
if (options->callback) {
|
||||
thread_bool_set(&ui_info.loop, false);
|
||||
rz_atomic_bool_set(ui_info.loop, false);
|
||||
rz_th_wait(user_thread);
|
||||
rz_th_free(user_thread);
|
||||
thread_bool_fini(&ui_info.loop);
|
||||
rz_atomic_bool_free(ui_info.loop);
|
||||
|
||||
RzBaseFindThreadInfo th_info;
|
||||
th_info.n_threads = pool_size;
|
||||
|
|
@ -502,7 +476,7 @@ rz_basefind_end:
|
|||
continue;
|
||||
}
|
||||
BaseFindThreadData *bftd = rz_th_get_user(th);
|
||||
thread_bool_fini(&bftd->loop);
|
||||
rz_atomic_bool_free(bftd->loop);
|
||||
free(bftd);
|
||||
}
|
||||
rz_th_pool_free(pool);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ SECURITY IMPLICATIONS
|
|||
#define rtr_host core->rtr_host
|
||||
|
||||
static RzSocket *s = NULL;
|
||||
static RzThread *httpthread = NULL;
|
||||
static RzThread *rapthread = NULL;
|
||||
static const char *listenport = NULL;
|
||||
|
||||
|
|
@ -44,30 +43,17 @@ typedef struct {
|
|||
const char *file;
|
||||
} TextLog;
|
||||
|
||||
typedef struct {
|
||||
RzCore *core;
|
||||
int launch;
|
||||
int browse;
|
||||
char *path;
|
||||
} HttpThread;
|
||||
|
||||
typedef struct {
|
||||
RzCore *core;
|
||||
char *input;
|
||||
RzAtomicBool *loop;
|
||||
} RapThread;
|
||||
|
||||
RZ_API void rz_core_wait(RzCore *core) {
|
||||
rz_cons_singleton()->context->breaked = true;
|
||||
if (httpthread) {
|
||||
rz_th_kill(httpthread);
|
||||
}
|
||||
if (rapthread) {
|
||||
rz_th_kill(rapthread);
|
||||
}
|
||||
if (httpthread) {
|
||||
rz_th_wait(httpthread);
|
||||
}
|
||||
if (rapthread) {
|
||||
RapThread *rt = rz_th_get_user(rapthread);
|
||||
rz_atomic_bool_set(rt->loop, false);
|
||||
rz_th_wait(rapthread);
|
||||
}
|
||||
}
|
||||
|
|
@ -853,8 +839,11 @@ static void *rz_core_rtr_rap_thread(RapThread *rt) {
|
|||
if (!rt || !rt->core) {
|
||||
return false;
|
||||
}
|
||||
while (rz_core_rtr_rap_run(rt->core, rt->input))
|
||||
;
|
||||
bool loop = true;
|
||||
while (loop) {
|
||||
loop = rz_atomic_bool_get(rt->loop) &&
|
||||
rz_core_rtr_rap_run(rt->core, rt->input);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -890,7 +879,8 @@ RZ_API void rz_core_rtr_cmd(RzCore *core, const char *input) {
|
|||
}
|
||||
rap_th->core = core;
|
||||
rap_th->input = strdup(input + 1);
|
||||
// RapThread rt = { core, strdup (input + 1) };
|
||||
rap_th->loop = rz_atomic_bool_new(true);
|
||||
|
||||
rapthread = rz_th_new((RzThreadFunction)rz_core_rtr_rap_thread, rap_th);
|
||||
if (!rap_th) {
|
||||
RZ_LOG_ERROR("cannot spawn the RzThread\n");
|
||||
|
|
|
|||
|
|
@ -488,37 +488,9 @@ the_end : {
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void *rz_core_rtr_http_thread (HttpThread *ht) {
|
||||
if (!ht || !ht->core) {
|
||||
return false;
|
||||
}
|
||||
int ret = 0;
|
||||
do {
|
||||
ret = rz_core_rtr_http_run (ht->core, ht->launch, ht->browse, ht->path);
|
||||
RZ_FREE (ht->path);
|
||||
if (ret) {
|
||||
int p = rz_config_get_i (ht->core->config, "http.port");
|
||||
rz_config_set_i (ht->core->config, "http.port", p + 1);
|
||||
if (p >= rz_config_get_i (ht->core->config, "http.maxport")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(ret);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
RZ_API int rz_core_rtr_http(RzCore *core, int launch, int browse, const char *path) {
|
||||
int ret;
|
||||
int ret = 0;
|
||||
if (launch == '-') {
|
||||
if (httpthread) {
|
||||
eprintf("Press ^C to stop the webserver\n");
|
||||
rz_th_kill_free(httpthread);
|
||||
httpthread = NULL;
|
||||
} else {
|
||||
eprintf("No webserver running\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (core->http_up) {
|
||||
|
|
@ -531,27 +503,6 @@ RZ_API int rz_core_rtr_http(RzCore *core, int launch, int browse, const char *pa
|
|||
}
|
||||
return rz_core_cmdf(core, "& Rh%s", path);
|
||||
}
|
||||
#if 0
|
||||
if (httpthread) {
|
||||
eprintf ("HTTP Thread is already running\n");
|
||||
eprintf ("This is experimental and probably buggy. Use at your own risk\n");
|
||||
eprintf ("TODO: Use different eval environ for scr. for the web\n");
|
||||
eprintf ("TODO: Visual mode should be enabled on local\n");
|
||||
} else {
|
||||
const char *tpath = rz_str_trim_head_ro (path + 1);
|
||||
//HttpThread ht = { core, launch, strdup (tpath) };
|
||||
HttpThread *ht = calloc (sizeof (HttpThread), 1);
|
||||
ht->core = core;
|
||||
ht->launch = launch;
|
||||
ht->browse = browse;
|
||||
ht->path = strdup (tpath);
|
||||
httpthread = rz_th_new ((RzThreadFunction)rz_core_rtr_http_thread, ht);
|
||||
rz_th_setname (httpthread, "httpthread");
|
||||
eprintf ("Background http server started.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
ret = rz_core_rtr_http_run(core, launch, browse, path);
|
||||
} while (ret == -2);
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ typedef struct rz_th_pool_t RzThreadPool;
|
|||
typedef struct rz_th_queue_t RzThreadQueue;
|
||||
typedef void *(*RzThreadFunction)(void *user);
|
||||
|
||||
typedef struct rz_atomic_bool_t RzAtomicBool;
|
||||
|
||||
#ifdef RZ_API
|
||||
RZ_API RZ_OWN RzThread *rz_th_new(RZ_NONNULL RzThreadFunction function, RZ_NULLABLE void *user);
|
||||
RZ_API RZ_OWN void *rz_th_get_user(RZ_NONNULL RzThread *th);
|
||||
RZ_API RZ_OWN void *rz_th_get_retv(RZ_NONNULL RzThread *th);
|
||||
RZ_API bool rz_th_wait(RZ_NONNULL RzThread *th);
|
||||
RZ_API void rz_th_free(RZ_NULLABLE RzThread *th);
|
||||
RZ_API void rz_th_kill(RZ_NONNULL RzThread *th);
|
||||
RZ_API void rz_th_kill_free(RZ_NONNULL RzThread *th);
|
||||
RZ_API bool rz_th_set_name(RZ_NONNULL RzThread *th, RZ_NONNULL const char *name);
|
||||
RZ_API bool rz_th_get_name(RZ_NONNULL RzThread *th, RZ_NONNULL RZ_OUT char *name, size_t len);
|
||||
RZ_API bool rz_th_set_affinity(RZ_NONNULL RzThread *th, int cpuid);
|
||||
|
|
@ -59,12 +59,12 @@ RZ_API void rz_th_cond_free(RZ_NULLABLE RzThreadCond *cond);
|
|||
|
||||
RZ_API size_t rz_th_physical_core_number();
|
||||
RZ_API size_t rz_th_request_physical_cores(size_t max_cores);
|
||||
|
||||
RZ_API RZ_OWN RzThreadPool *rz_th_pool_new(size_t max_threads);
|
||||
RZ_API void rz_th_pool_free(RZ_NULLABLE RzThreadPool *pool);
|
||||
RZ_API bool rz_th_pool_add_thread(RZ_NONNULL RzThreadPool *pool, RZ_NONNULL RzThread *thread);
|
||||
RZ_API RZ_BORROW RzThread *rz_th_pool_get_thread(RZ_NONNULL RzThreadPool *pool, size_t index);
|
||||
RZ_API bool rz_th_pool_wait(RZ_NONNULL RzThreadPool *pool);
|
||||
RZ_API bool rz_th_pool_kill(RZ_NONNULL RzThreadPool *pool);
|
||||
RZ_API size_t rz_th_pool_size(RZ_NULLABLE RzThreadPool *pool);
|
||||
|
||||
RZ_API RZ_OWN RzThreadQueue *rz_th_queue_new(size_t max_size, RZ_NULLABLE RzListFree qfree);
|
||||
|
|
@ -75,6 +75,11 @@ RZ_API RZ_OWN void *rz_th_queue_wait_pop(RZ_NONNULL RzThreadQueue *queue, bool t
|
|||
RZ_API bool rz_th_queue_is_empty(RZ_NULLABLE RzThreadQueue *queue);
|
||||
RZ_API bool rz_th_queue_is_full(RZ_NULLABLE RzThreadQueue *queue);
|
||||
|
||||
RZ_API RZ_OWN RzAtomicBool *rz_atomic_bool_new(bool value);
|
||||
RZ_API void rz_atomic_bool_free(RZ_NULLABLE RzAtomicBool *tbool);
|
||||
RZ_API bool rz_atomic_bool_get(RZ_NONNULL RzAtomicBool *tbool);
|
||||
RZ_API void rz_atomic_bool_set(RZ_NONNULL RzAtomicBool *tbool, bool value);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -64,9 +64,10 @@ rz_util_sources = [
|
|||
'thread.c',
|
||||
'thread_cond.c',
|
||||
'thread_lock.c',
|
||||
'thread_sem.c',
|
||||
'thread_pool.c',
|
||||
'thread_queue.c',
|
||||
'thread_sem.c',
|
||||
'thread_types.c',
|
||||
'time.c',
|
||||
'tree.c',
|
||||
'ubase64.c',
|
||||
|
|
|
|||
|
|
@ -221,29 +221,6 @@ RZ_API RZ_OWN RzThread *rz_th_new(RZ_NONNULL RzThreadFunction function, RZ_NULLA
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Force-stops a thread
|
||||
*
|
||||
* \param RzThread The thread to stop
|
||||
*/
|
||||
RZ_API void rz_th_kill(RZ_NONNULL RzThread *th) {
|
||||
rz_return_if_fail(th);
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
if (!pthread_kill(th->tid, 0)) {
|
||||
#ifdef __ANDROID__
|
||||
pthread_kill(th->tid, 9);
|
||||
#else
|
||||
pthread_cancel(th->tid);
|
||||
#endif
|
||||
}
|
||||
#elif __WINDOWS__
|
||||
if (WaitForSingleObject(th->tid, 0)) {
|
||||
TerminateThread(th->tid, -1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Awaits indefinetely for a thread to join
|
||||
*
|
||||
|
|
@ -276,17 +253,6 @@ RZ_API void rz_th_free(RZ_NULLABLE RzThread *th) {
|
|||
free(th);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Stops the thread and frees the RzThread structure
|
||||
*
|
||||
* \param th The thread to stop and free.
|
||||
*/
|
||||
RZ_API void rz_th_kill_free(RZ_NONNULL RzThread *th) {
|
||||
rz_return_if_fail(th);
|
||||
rz_th_kill(th);
|
||||
rz_th_free(th);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns user pointer of thread
|
||||
*
|
||||
|
|
|
|||
|
|
@ -179,26 +179,6 @@ RZ_API bool rz_th_pool_wait(RZ_NONNULL RzThreadPool *pool) {
|
|||
return has_exited;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Force-stops all threads in the thread pool
|
||||
*
|
||||
* \param pool The thread pool to kill
|
||||
*
|
||||
* \return true if managed to kill all threads, otherwise false
|
||||
*/
|
||||
RZ_API bool rz_th_pool_kill(RZ_NONNULL RzThreadPool *pool) {
|
||||
rz_return_val_if_fail(pool, false);
|
||||
bool has_exited = false;
|
||||
for (ut32 i = 0; i < pool->size; ++i) {
|
||||
if (pool->threads[i]) {
|
||||
RZ_LOG_DEBUG("thread: killing thread %u\n", i);
|
||||
rz_th_kill(pool->threads[i]);
|
||||
has_exited = true;
|
||||
}
|
||||
}
|
||||
return has_exited;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the thread pool size
|
||||
*
|
||||
|
|
|
|||
73
librz/util/thread_types.c
Normal file
73
librz/util/thread_types.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// SPDX-FileCopyrightText: 2021-2022 deroad <wargio@libero.it>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_th.h>
|
||||
#include <rz_util.h>
|
||||
|
||||
/** \file thread_types.c
|
||||
* The native types should actually be real atomic types but these should be
|
||||
* falling back in similar structs in case of insupported atomic types.
|
||||
*/
|
||||
|
||||
struct rz_atomic_bool_t {
|
||||
bool value; ///< The value to get/set safely
|
||||
RzThreadLock *lock; ///< The lock related to the single value
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Initialize a thread safe bool type container
|
||||
*
|
||||
* \param[in] value The initial value status
|
||||
*
|
||||
* \return On success returns a valid pointer, otherwise NULL
|
||||
*/
|
||||
RZ_API RZ_OWN RzAtomicBool *rz_atomic_bool_new(bool value) {
|
||||
RzAtomicBool *tbool = RZ_NEW0(RzAtomicBool);
|
||||
if (!tbool) {
|
||||
return NULL;
|
||||
}
|
||||
tbool->lock = rz_th_lock_new(false);
|
||||
tbool->value = true;
|
||||
return tbool;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Frees a RzAtomicBool structure
|
||||
*
|
||||
* \param tbool The RzAtomicBool structure to free
|
||||
*/
|
||||
RZ_API void rz_atomic_bool_free(RZ_NULLABLE RzAtomicBool *tbool) {
|
||||
if (!tbool) {
|
||||
return;
|
||||
}
|
||||
rz_th_lock_free(tbool->lock);
|
||||
free(tbool);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Gets the current value hold by the RzAtomicBool structure
|
||||
*
|
||||
* \param[in] tbool The RzAtomicBool to safely access
|
||||
*
|
||||
* \return Returns a copy of the stored value
|
||||
*/
|
||||
RZ_API bool rz_atomic_bool_get(RZ_NONNULL RzAtomicBool *tbool) {
|
||||
rz_return_val_if_fail(tbool, false);
|
||||
rz_th_lock_enter(tbool->lock);
|
||||
bool value = tbool->value;
|
||||
rz_th_lock_leave(tbool->lock);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the value int the RzAtomicBool structure
|
||||
*
|
||||
* \param tbool The RzAtomicBool to safely modify
|
||||
* \param[in] value The new value to set
|
||||
*/
|
||||
RZ_API void rz_atomic_bool_set(RZ_NONNULL RzAtomicBool *tbool, bool value) {
|
||||
rz_return_if_fail(tbool);
|
||||
rz_th_lock_enter(tbool->lock);
|
||||
tbool->value = value;
|
||||
rz_th_lock_leave(tbool->lock);
|
||||
}
|
||||
Loading…
Reference in a new issue