diff options
author | Jo-Philipp Wich <jo@mein.io> | 2024-10-19 16:06:09 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2024-12-02 15:25:39 +0100 |
commit | efeb578065523b2882d71d91f38cd63115928b7a (patch) | |
tree | 43017d5d8683168f4a9ca2453fcf3d5f1975d34f /types.c | |
parent | 47b54cf5a4b6166944efa4ee4cd023d73ebe6c3e (diff) |
types, vm: refactor usage of global variables
Introduce an extensible private TLS context structure and use it within
libucode to store global state such as active object iterators.
This allows using libucode concurrently in multiple threads without
unintentionally sharing global state among them.
Also adjust the signal dispatching setup logic in `uc_vm_init()` to only
enable signal handling if no other VM in the same thread already handles
signals.
Suggested-by: Isaac de Wolff <idewolff@vincitech.nl>
[squash commits, move signal handler vm pointer and object iterator list
into common extensible TLS context, whitespace and naming adjustments,
extended signal setup logic]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'types.c')
-rw-r--r-- | types.c | 26 |
1 files changed, 18 insertions, 8 deletions
@@ -29,11 +29,6 @@ #include "ucode/vm.h" #include "ucode/program.h" -uc_list_t uc_object_iterators = { - .prev = &uc_object_iterators, - .next = &uc_object_iterators -}; - static char *uc_default_search_path[] = { LIB_SEARCH_PATH }; uc_parse_config_t uc_default_parse_config = { @@ -898,7 +893,7 @@ ucv_array_length(uc_value_t *uv) static void ucv_free_object_entry(struct lh_entry *entry) { - uc_list_foreach(item, &uc_object_iterators) { + uc_list_foreach(item, &uc_thread_context_get()->object_iterators) { uc_object_iterator_t *iter = (uc_object_iterator_t *)item; if (iter->u.pos == entry) @@ -955,7 +950,7 @@ ucv_object_add(uc_value_t *uv, const char *key, uc_value_t *val) /* insert will rehash table, backup affected iterator states */ if (rehash) { - uc_list_foreach(item, &uc_object_iterators) { + uc_list_foreach(item, &uc_thread_context_get()->object_iterators) { uc_object_iterator_t *iter = (uc_object_iterator_t *)item; if (iter->table != object->table) @@ -979,7 +974,7 @@ ucv_object_add(uc_value_t *uv, const char *key, uc_value_t *val) /* restore affected iterator state pointer after rehash */ if (rehash) { - uc_list_foreach(item, &uc_object_iterators) { + uc_list_foreach(item, &uc_thread_context_get()->object_iterators) { uc_object_iterator_t *iter = (uc_object_iterator_t *)item; if (iter->table != object->table) @@ -2481,3 +2476,18 @@ uc_search_path_init(uc_search_path_t *search_path) for (i = 0; i < ARRAY_SIZE(uc_default_search_path); i++) uc_vector_push(search_path, xstrdup(uc_default_search_path[i])); } + + +static __thread uc_thread_context_t *tls_ctx; + +uc_thread_context_t * +uc_thread_context_get(void) +{ + if (tls_ctx == NULL) { + tls_ctx = xalloc(sizeof(*tls_ctx)); + tls_ctx->object_iterators.prev = &tls_ctx->object_iterators; + tls_ctx->object_iterators.next = &tls_ctx->object_iterators; + } + + return tls_ctx; +} |