Remove rz_th_kill, rz_th_kill_free and rz_th_pool_kill (#2790)

This commit is contained in:
Giovanni 2022-07-08 14:54:51 +02:00 committed by GitHub
parent 906fe97252
commit 522ab57c75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 130 additions and 169 deletions

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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");

View file

@ -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);

View file

@ -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

View file

@ -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',

View file

@ -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
*

View file

@ -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
View 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);
}