diff options
author | Koichi Sasada <[email protected]> | 2023-11-17 02:29:11 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2023-12-08 13:16:19 +0900 |
commit | 352a885a0f1a4d4576c686301ee71ea887a345e5 (patch) | |
tree | afb66f30ac5e3056d3cf3b96ca71d5c78b4f77a0 /include/ruby/thread.h | |
parent | 9b7a964318d04beb82680ff1d0c6eb571f4b8b5e (diff) |
Thread specific storage APIs
This patch introduces thread specific storage APIs
for tools which use `rb_internal_thread_event_hook` APIs.
* `rb_internal_thread_specific_key_create()` to create a tool specific
thread local storage key and allocate the storage if not available.
* `rb_internal_thread_specific_set()` sets a data to thread and tool
specific storage.
* `rb_internal_thread_specific_get()` gets a data in thread and tool
specific storage.
Note that `rb_internal_thread_specific_get|set(thread_val, key)`
can be called without GVL and safe for async signal and safe for
multi-threading (native threads). So you can call it in any internal
thread event hooks. Further more you can call it from other native
threads. Of course `thread_val` should be living while accessing the
data from this function.
Note that you should not forget to clean up the set data.
Diffstat (limited to 'include/ruby/thread.h')
-rw-r--r-- | include/ruby/thread.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/include/ruby/thread.h b/include/ruby/thread.h index f11cc19086..496f026334 100644 --- a/include/ruby/thread.h +++ b/include/ruby/thread.h @@ -267,6 +267,46 @@ rb_internal_thread_event_hook_t *rb_internal_thread_add_event_hook( bool rb_internal_thread_remove_event_hook( rb_internal_thread_event_hook_t * hook); + +typedef int rb_internal_thread_specific_key_t; +#define RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX 8 +/** + * Create a key to store thread specific data. + * + * These APIs are designed for tools using + * rb_internal_thread_event_hook APIs. + * + * Note that only `RB_INTERNAL_THREAD_SPECIFIC_KEY_MAX` keys + * can be created. raises `ThreadError` if exceeded. + * + * Usage: + * // at initialize time: + * int tool_key; // gvar + * Init_tool() { + * tool_key = rb_internal_thread_specific_key_create(); + * } + * + * // at any timing: + * rb_internal_thread_pecific_set(thread, tool_key, per_thread_data); + * ... + * per_thread_data = rb_internal_thread_specific_get(thread, tool_key); + */ +rb_internal_thread_specific_key_t rb_internal_thread_specific_key_create(void); + +/** + * Get thread and tool specific data. + * + * This function is async signal safe and thread safe. + */ +void *rb_internal_thread_specific_get(VALUE thread_val, rb_internal_thread_specific_key_t key); + +/** + * Set thread and tool specific data. + * + * This function is async signal safe and thread safe. + */ +void rb_internal_thread_specific_set(VALUE thread_val, rb_internal_thread_specific_key_t key, void *data); + RBIMPL_SYMBOL_EXPORT_END() #endif /* RUBY_THREAD_H */ |