Ruby
3.4.0dev (2024-11-05 revision 348a53415339076afc4a02fcd09f3ae36e9c4c61)
|
Public APIs related to rb_cThread. More...
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/cast.h"
#include "ruby/internal/config.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
Go to the source code of this file.
Macros | |
#define | RUBY_UBF_IO RBIMPL_CAST((rb_unblock_function_t *)-1) |
A special UBF for blocking IO operations. More... | |
#define | RUBY_UBF_PROCESS RBIMPL_CAST((rb_unblock_function_t *)-1) |
A special UBF for blocking process operations. More... | |
Typedefs | |
typedef void | rb_unblock_function_t(void *) |
This is the type of UBFs. More... | |
Functions | |
void | rb_thread_schedule (void) |
Tries to switch to another thread. More... | |
int | rb_thread_wait_fd (int fd) |
Blocks the current thread until the given file descriptor is ready to be read. More... | |
int | rb_thread_fd_writable (int fd) |
Identical to rb_thread_wait_fd(), except it blocks the current thread until the given file descriptor is ready to be written. More... | |
void | rb_thread_fd_close (int fd) |
Notifies a closing of a file descriptor to other threads. More... | |
int | rb_thread_alone (void) |
Checks if the thread this function is running is the only thread that is currently alive. More... | |
void | rb_thread_sleep (int sec) |
Blocks for the given period of time. More... | |
void | rb_thread_sleep_forever (void) |
Blocks indefinitely. More... | |
void | rb_thread_sleep_deadly (void) |
Identical to rb_thread_sleep_forever(), except the thread calling this function is considered "dead" when our deadlock checker is triggered. More... | |
VALUE | rb_thread_stop (void) |
Stops the current thread. More... | |
VALUE | rb_thread_wakeup (VALUE thread) |
Marks a given thread as eligible for scheduling. More... | |
VALUE | rb_thread_wakeup_alive (VALUE thread) |
Identical to rb_thread_wakeup(), except it doesn't raise on an already killed thread. More... | |
VALUE | rb_thread_run (VALUE thread) |
This is a rb_thread_wakeup() + rb_thread_schedule() combo. More... | |
VALUE | rb_thread_kill (VALUE thread) |
Terminates the given thread. More... | |
VALUE | rb_thread_create (VALUE(*f)(void *g), void *g) |
Creates a Ruby thread that is backended by a C function. More... | |
void | rb_thread_wait_for (struct timeval time) |
Identical to rb_thread_sleep(), except it takes struct timeval instead. More... | |
VALUE | rb_thread_current (void) |
Obtains the "current" thread. More... | |
VALUE | rb_thread_main (void) |
Obtains the "main" thread. More... | |
VALUE | rb_thread_local_aref (VALUE thread, ID key) |
This badly named function reads from a Fiber local storage. More... | |
VALUE | rb_thread_local_aset (VALUE thread, ID key, VALUE val) |
This badly named function writes to a Fiber local storage. More... | |
void | rb_thread_atfork (void) |
A pthread_atfork(3posix) -like API. More... | |
void | rb_thread_atfork_before_exec (void) |
:FIXME: situation of this function is unclear. More... | |
VALUE | rb_exec_recursive (VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h) |
"Recursion" API entry point. More... | |
VALUE | rb_exec_recursive_paired (VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h) |
Identical to rb_exec_recursive(), except it checks for the recursion on the ordered pair of { g, p } instead of just g . More... | |
VALUE | rb_exec_recursive_outer (VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h) |
Identical to rb_exec_recursive(), except it calls f for outermost recursion only. More... | |
VALUE | rb_exec_recursive_paired_outer (VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h) |
Identical to rb_exec_recursive_outer(), except it checks for the recursion on the ordered pair of { g, p } instead of just g . More... | |
void | rb_thread_check_ints (void) |
Checks for interrupts. More... | |
int | rb_thread_interrupted (VALUE thval) |
Checks if the thread's execution was recently interrupted. More... | |
VALUE | rb_mutex_new (void) |
Creates a mutex. More... | |
VALUE | rb_mutex_locked_p (VALUE mutex) |
Queries if there are any threads that holds the lock. More... | |
VALUE | rb_mutex_trylock (VALUE mutex) |
Attempts to lock the mutex, without waiting for other threads to unlock it. More... | |
VALUE | rb_mutex_lock (VALUE mutex) |
Attempts to lock the mutex. More... | |
VALUE | rb_mutex_unlock (VALUE mutex) |
Releases the mutex. More... | |
VALUE | rb_mutex_sleep (VALUE self, VALUE timeout) |
Releases the lock held in the mutex and waits for the period of time; reacquires the lock on wakeup. More... | |
VALUE | rb_mutex_synchronize (VALUE mutex, VALUE(*func)(VALUE arg), VALUE arg) |
Obtains the lock, runs the passed function, and releases the lock when it completes. More... | |
Public APIs related to rb_cThread.
RBIMPL
or rbimpl
are implementation details. Don't take them as canon. They could rapidly appear then vanish. The name (path) of this header file is also an implementation detail. Do not expect it to persist at the place it is now. Developers are free to move it anywhere anytime at will. __VA_ARGS__
is always available. We assume C99 for ruby itself but we don't assume languages of extension libraries. They could be written in C++98. Definition in file thread.h.
#define RUBY_UBF_IO RBIMPL_CAST((rb_unblock_function_t *)-1) |
#define RUBY_UBF_PROCESS RBIMPL_CAST((rb_unblock_function_t *)-1) |
typedef void rb_unblock_function_t(void *) |
This is the type of UBFs.
An UBF is a function that unblocks a blocking region. For instance when a thread is blocking due to pselect(3posix)
, it is highly expected that pthread_kill(3posix)
can interrupt the system call and the thread could revive. Or when a thread is blocking due to waitpid(3posix)
, it is highly expected that killing the waited process should suffice. An UBF is a function that does such things. Designing your own UBF needs deep understanding of why your blocking region blocks, how threads work in ruby, and a matter of luck. It often is the case you simply cannot cancel something that had already begun.
"Recursion" API entry point.
This basically calls the given function with the given arguments, but additionally with recursion flag. The flag is set to 1 if the execution have already experienced the passed g
parameter before.
[in] | f | The function that possibly recurs. |
[in,out] | g | Passed as-is to f . |
[in,out] | h | Passed as-is to f . |
Referenced by rb_io_puts().
Identical to rb_exec_recursive(), except it calls f
for outermost recursion only.
Inner recursions yield calls to rb_throw_obj().
[in] | f | The function that possibly recurs. |
[in,out] | g | Passed as-is to f . |
[in,out] | h | Passed as-is to f . |
Identical to rb_exec_recursive(), except it checks for the recursion on the ordered pair of { g, p }
instead of just g
.
[in] | f | The function that possibly recurs. |
[in,out] | g | Passed as-is to f . |
[in] | p | Paired object for recursion detection. |
[in,out] | h | Passed as-is to f . |
Referenced by rb_ary_cmp(), and rb_num_coerce_bit().
VALUE rb_exec_recursive_paired_outer | ( | VALUE(*)(VALUE g, VALUE h, int r) | f, |
VALUE | g, | ||
VALUE | p, | ||
VALUE | h | ||
) |
Identical to rb_exec_recursive_outer(), except it checks for the recursion on the ordered pair of { g, p }
instead of just g
.
It can also be seen as a routine identical to rb_exec_recursive_paired(), except it calls f
for outermost recursion only. Inner recursions yield calls to rb_throw_obj().
[in] | f | The function that possibly recurs. |
[in,out] | g | Passed as-is to f . |
[in] | p | Paired object for recursion detection. |
[in,out] | h | Passed as-is to f . |
Attempts to lock the mutex.
It waits until the mutex gets available.
[out] | mutex | The mutex to lock. |
rb_eThreadError | Recursive deadlock situation. |
Definition at line 432 of file thread_sync.c.
Referenced by rb_mutex_synchronize().
Queries if there are any threads that holds the lock.
[in] | mutex | The mutex in question. |
RUBY_Qtrue | The mutex is locked by someone. |
RUBY_Qfalse | The mutex is not locked by anyone. |
Definition at line 203 of file thread_sync.c.
VALUE rb_mutex_new | ( | void | ) |
Creates a mutex.
Definition at line 191 of file thread_sync.c.
Releases the lock held in the mutex and waits for the period of time; reacquires the lock on wakeup.
[out] | self | The target mutex. |
[in] | timeout | Duration, in seconds, in rb_cNumeric. |
rb_eArgError | timeout is negative. |
rb_eRangeError | timeout is out of range of time_t . |
rb_eThreadError | The mutex is not owned by the current thread. |
Definition at line 567 of file thread_sync.c.
Obtains the lock, runs the passed function, and releases the lock when it completes.
[out] | mutex | The mutex to lock. |
[in] | func | What to do during the mutex is locked. |
[in,out] | arg | Passed as-is to func . |
Definition at line 634 of file thread_sync.c.
Referenced by rb_autoload_load().
Attempts to lock the mutex, without waiting for other threads to unlock it.
Failure in locking the mutex can be detected by the return value.
[out] | mutex | The mutex to lock. |
RUBY_Qtrue | Successfully locked by the current thread. |
RUBY_Qfalse | Otherwise. |
Definition at line 252 of file thread_sync.c.
Releases the mutex.
[out] | mutex | The mutex to unlock. |
rb_eThreadError | The mutex is not owned by the current thread. |
Definition at line 505 of file thread_sync.c.
Referenced by rb_mutex_sleep(), and rb_mutex_synchronize().
int rb_thread_alone | ( | void | ) |
Checks if the thread this function is running is the only thread that is currently alive.
1 | Yes it is. |
0 | No it isn't. |
Definition at line 3817 of file thread.c.
Referenced by rb_thread_stop().
void rb_thread_atfork | ( | void | ) |
void rb_thread_atfork_before_exec | ( | void | ) |
void rb_thread_check_ints | ( | void | ) |
Checks for interrupts.
In ruby, signals are masked by default. You can call this function at will to check if there are pending signals. In case there are, they would be handled in this function.
If your extension library has a function that takes a long time, consider calling it periodically.
Definition at line 1416 of file thread.c.
Referenced by rb_io_maybe_wait(), rb_io_wait_readable(), and rb_io_wait_writable().
Creates a Ruby thread that is backended by a C function.
[in] | f | The function to run on a thread. |
[in,out] | g | Passed through to f . |
rb_eThreadError | Could not create a ruby thread. |
rb_eSystemCallError | Situations like EPERM . |
Referenced by rb_detach_process(), and ruby::backward::cxxanyargs::rb_thread_create().
VALUE rb_thread_current | ( | void | ) |
Obtains the "current" thread.
Definition at line 2955 of file thread.c.
Referenced by rb_f_kill().
void rb_thread_fd_close | ( | int | fd | ) |
Notifies a closing of a file descriptor to other threads.
Multiple threads can wait for the given file descriptor at once. If such file descriptor is closed, threads need to start propagating their exceptions. This is the API to kick that process.
[in] | fd | A file descriptor. |
int rb_thread_fd_writable | ( | int | fd | ) |
Identical to rb_thread_wait_fd(), except it blocks the current thread until the given file descriptor is ready to be written.
[in] | fd | A file descriptor. |
rb_eIOError | Closed stream. |
rb_eSystemCallError | Situations like EBADF. |
int rb_thread_interrupted | ( | VALUE | thval | ) |
Checks if the thread's execution was recently interrupted.
If called from that thread, this function can be used to detect spurious wake-ups.
[in] | thval | Thread in question. |
0 | The thread was not interrupted. |
otherwise | The thread was interrupted recently. |
Terminates the given thread.
Unlike a stopped thread, a killed thread could never be revived. This function does return, when passed e.g. an already killed thread. But if the passed thread is the only one, or a special thread called "main", then it also terminates the entire process.
[out] | thread | The thread to terminate. |
rb_eFatal | The passed thread is the running thread. |
rb_eSystemExit | The passed thread is the last thread. |
Definition at line 2737 of file thread.c.
Referenced by rb_nogvl().
This badly named function reads from a Fiber local storage.
When this function was born there was no such thing like a Fiber. The world was innocent. But now... This is a Fiber local storage. Sorry.
[in] | thread | Thread that the target Fiber is running. |
[in] | key | The name of the Fiber local storage to read. |
RUBY_Qnil | No such storage. |
otherwise | The value stored at key . |
This badly named function writes to a Fiber local storage.
When this function was born there was no such thing like a Fiber. The world was innocent. But now... This is a Fiber local storage. Sorry.
[in] | thread | Thread that the target Fiber is running. |
[in] | key | The name of the Fiber local storage to write. |
[in] | val | The new value of the storage. |
rb_eFrozenError | thread is frozen. |
val
as-is. key
has value of val
. Definition at line 3692 of file thread.c.
Referenced by rb_detach_process().
VALUE rb_thread_main | ( | void | ) |
Obtains the "main" thread.
There are threads called main. Historically the (only) main thread was the one which runs when the process boots. Now that we have Ractor, there are more than one main threads.
This is a rb_thread_wakeup() + rb_thread_schedule() combo.
[out] | thread | Thread in question to wake up. |
rb_eThreadError | Stop flogging a dead horse. |
void rb_thread_schedule | ( | void | ) |
Tries to switch to another thread.
This function blocks until the current thread re-acquires the GVL.
rb_eInterrupt | Operation interrupted. |
Definition at line 1464 of file thread.c.
Referenced by rb_thread_run().
void rb_thread_sleep | ( | int | sec | ) |
void rb_thread_sleep_deadly | ( | void | ) |
Identical to rb_thread_sleep_forever(), except the thread calling this function is considered "dead" when our deadlock checker is triggered.
rb_eInterrupt | Interrupted. |
Definition at line 1376 of file thread.c.
Referenced by rb_thread_stop().
void rb_thread_sleep_forever | ( | void | ) |
Blocks indefinitely.
rb_eInterrupt | Interrupted. |
Definition at line 1369 of file thread.c.
Referenced by rb_thread_fd_select().
VALUE rb_thread_stop | ( | void | ) |
int rb_thread_wait_fd | ( | int | fd | ) |
void rb_thread_wait_for | ( | struct timeval | time | ) |
Identical to rb_thread_sleep(), except it takes struct timeval
instead.
[in] | time | Duration. |
rb_eInterrupt | Interrupted. |
Definition at line 1401 of file thread.c.
Referenced by rb_thread_fd_select(), and rb_thread_sleep().
Marks a given thread as eligible for scheduling.
[out] | thread | Thread in question to wake up. |
rb_eThreadError | Stop flogging a dead horse. |
Definition at line 2832 of file thread.c.
Referenced by rb_thread_run().
Identical to rb_thread_wakeup(), except it doesn't raise on an already killed thread.
[out] | thread | A thread to wake up. |
RUBY_Qnil | thread is already killed. |
otherwise | thread is alive. |
Definition at line 2841 of file thread.c.
Referenced by rb_thread_wakeup().