Ruby  3.4.0dev (2024-11-22 revision 37a72b0150ec36b4ea27175039afc28c62207b0c)
Macros | Typedefs | Functions
thread.h File Reference

(37a72b0150ec36b4ea27175039afc28c62207b0c)

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"
Include dependency graph for thread.h:
This graph shows which files directly or indirectly include this file:

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

Detailed Description

Public APIs related to rb_cThread.

Author
Ruby developers ruby-.nosp@m.core.nosp@m.@ruby.nosp@m.-lan.nosp@m.g.org
Warning
Symbols prefixed with either 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.
Note
To ruby-core: remember that this header can be possibly recursively included from extension libraries written in C++. Do not expect for instance __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.

Macro Definition Documentation

◆ RUBY_UBF_IO

#define RUBY_UBF_IO   RBIMPL_CAST((rb_unblock_function_t *)-1)

A special UBF for blocking IO operations.

You need deep understanding of what this actually do before using. Basically you should not use it from extension libraries. It is too easy to mess up.

Definition at line 382 of file thread.h.

◆ RUBY_UBF_PROCESS

#define RUBY_UBF_PROCESS   RBIMPL_CAST((rb_unblock_function_t *)-1)

A special UBF for blocking process operations.

You need deep understanding of what this actually do before using. Basically you should not use it from extension libraries. It is too easy to mess up.

Definition at line 389 of file thread.h.

Typedef Documentation

◆ rb_unblock_function_t

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.

See also
rb_thread_call_without_gvl()

Definition at line 336 of file thread.h.

Function Documentation

◆ rb_exec_recursive()

VALUE rb_exec_recursive ( VALUE(*)(VALUE g, VALUE h, int r)  f,
VALUE  g,
VALUE  h 
)

"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.

Parameters
[in]fThe function that possibly recurs.
[in,out]gPassed as-is to f.
[in,out]hPassed as-is to f.
Returns
The return value of f.

Referenced by rb_io_puts().

◆ rb_exec_recursive_outer()

VALUE rb_exec_recursive_outer ( VALUE(*)(VALUE g, VALUE h, int r)  f,
VALUE  g,
VALUE  h 
)

Identical to rb_exec_recursive(), except it calls f for outermost recursion only.

Inner recursions yield calls to rb_throw_obj().

Parameters
[in]fThe function that possibly recurs.
[in,out]gPassed as-is to f.
[in,out]hPassed as-is to f.
Returns
The return value of f.

◆ rb_exec_recursive_paired()

VALUE rb_exec_recursive_paired ( VALUE(*)(VALUE g, VALUE h, int r)  f,
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.

Parameters
[in]fThe function that possibly recurs.
[in,out]gPassed as-is to f.
[in]pPaired object for recursion detection.
[in,out]hPassed as-is to f.

Referenced by rb_ary_cmp(), and rb_num_coerce_bit().

◆ rb_exec_recursive_paired_outer()

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().

Parameters
[in]fThe function that possibly recurs.
[in,out]gPassed as-is to f.
[in]pPaired object for recursion detection.
[in,out]hPassed as-is to f.

◆ rb_mutex_lock()

VALUE rb_mutex_lock ( VALUE  mutex)

Attempts to lock the mutex.

It waits until the mutex gets available.

Parameters
[out]mutexThe mutex to lock.
Exceptions
rb_eThreadErrorRecursive deadlock situation.
Returns
The passed mutex.
Postcondition
The mutex is owned by the current thread.

Definition at line 432 of file thread_sync.c.

Referenced by rb_mutex_synchronize().

◆ rb_mutex_locked_p()

VALUE rb_mutex_locked_p ( VALUE  mutex)

Queries if there are any threads that holds the lock.

Parameters
[in]mutexThe mutex in question.
Return values
RUBY_QtrueThe mutex is locked by someone.
RUBY_QfalseThe mutex is not locked by anyone.

Definition at line 203 of file thread_sync.c.

◆ rb_mutex_new()

VALUE rb_mutex_new ( void  )

Creates a mutex.

Returns
An allocated instance of rb_cMutex.

Definition at line 191 of file thread_sync.c.

◆ rb_mutex_sleep()

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.

Precondition
The lock has to be owned by the current thread beforehand.
Parameters
[out]selfThe target mutex.
[in]timeoutDuration, in seconds, in rb_cNumeric.
Exceptions
rb_eArgErrortimeout is negative.
rb_eRangeErrortimeout is out of range of time_t.
rb_eThreadErrorThe mutex is not owned by the current thread.
Returns
Number of seconds it actually slept.
Warning
It is a failure not to check the return value. This function can return spuriously for various reasons. Maybe other threads can rb_thread_wakeup(). Maybe an end user can press the Control and C key from the interactive console. On the other hand it can also take longer than the specified. The mutex could be locked by someone else. It waits then.
Postcondition
Upon successful return the passed mutex is owned by the current thread.

Definition at line 567 of file thread_sync.c.

◆ rb_mutex_synchronize()

VALUE rb_mutex_synchronize ( VALUE  mutex,
VALUE(*)(VALUE arg)  func,
VALUE  arg 
)

Obtains the lock, runs the passed function, and releases the lock when it completes.

Parameters
[out]mutexThe mutex to lock.
[in]funcWhat to do during the mutex is locked.
[in,out]argPassed as-is to func.

Definition at line 634 of file thread_sync.c.

Referenced by rb_autoload_load().

◆ rb_mutex_trylock()

VALUE rb_mutex_trylock ( VALUE  mutex)

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.

Parameters
[out]mutexThe mutex to lock.
Return values
RUBY_QtrueSuccessfully locked by the current thread.
RUBY_QfalseOtherwise.
Note
This function also returns RUBY_Qfalse when the mutex is already owned by the calling thread itself.

Definition at line 252 of file thread_sync.c.

◆ rb_mutex_unlock()

VALUE rb_mutex_unlock ( VALUE  mutex)

Releases the mutex.

Parameters
[out]mutexThe mutex to unlock.
Exceptions
rb_eThreadErrorThe mutex is not owned by the current thread.
Returns
The passed mutex.
Postcondition
Upon successful return the passed mutex is no longer owned by the current thread.

Definition at line 505 of file thread_sync.c.

Referenced by rb_mutex_sleep(), and rb_mutex_synchronize().

◆ rb_thread_alone()

int rb_thread_alone ( void  )

Checks if the thread this function is running is the only thread that is currently alive.

Return values
1Yes it is.
0No it isn't.

Definition at line 3844 of file thread.c.

Referenced by rb_thread_stop().

◆ rb_thread_atfork()

void rb_thread_atfork ( void  )

A pthread_atfork(3posix)-like API.

Ruby expects its child processes to call this function at the very beginning of their processes. If you plan to fork a process don't forget to call it.

Definition at line 4800 of file thread.c.

◆ rb_thread_atfork_before_exec()

void rb_thread_atfork_before_exec ( void  )

:FIXME: situation of this function is unclear.

It seems nobody uses it. Maybe a good idea to KonMari.

Definition at line 4805 of file thread.c.

◆ rb_thread_check_ints()

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.

Note
It might switch to another thread.

Definition at line 1432 of file thread.c.

Referenced by rb_io_maybe_wait(), rb_io_wait_readable(), and rb_io_wait_writable().

◆ rb_thread_create()

VALUE rb_thread_create ( VALUE(*)(void *g)  f,
void *  g 
)

Creates a Ruby thread that is backended by a C function.

Parameters
[in]fThe function to run on a thread.
[in,out]gPassed through to f.
Exceptions
rb_eThreadErrorCould not create a ruby thread.
rb_eSystemCallErrorSituations like EPERM.
Returns
Allocated instance of rb_cThread.
Note
This doesn't wait for anything.

Referenced by rb_detach_process(), and ruby::backward::cxxanyargs::rb_thread_create().

◆ rb_thread_current()

VALUE rb_thread_current ( void  )

Obtains the "current" thread.

Returns
The current thread of the current ractor of the current execution context.
Precondition
This function must be called from a thread controlled by ruby.

Definition at line 2982 of file thread.c.

Referenced by rb_f_kill().

◆ rb_thread_fd_close()

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.

Parameters
[in]fdA file descriptor.
Note
This function blocks until all the threads waiting for such fd have woken up.

Definition at line 2705 of file thread.c.

◆ rb_thread_fd_writable()

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.

Parameters
[in]fdA file descriptor.
Exceptions
rb_eIOErrorClosed stream.
rb_eSystemCallErrorSituations like EBADF.

Definition at line 1597 of file io.c.

◆ rb_thread_interrupted()

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.

Parameters
[in]thvalThread in question.
Return values
0The thread was not interrupted.
otherwiseThe thread was interrupted recently.

Definition at line 1449 of file thread.c.

◆ rb_thread_kill()

VALUE rb_thread_kill ( VALUE  thread)

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.

Parameters
[out]threadThe thread to terminate.
Exceptions
rb_eFatalThe passed thread is the running thread.
rb_eSystemExitThe passed thread is the last thread.
Returns
The passed thread.
Postcondition
Either the passed thread, or the process entirely, is killed.

Definition at line 2764 of file thread.c.

◆ rb_thread_local_aref()

VALUE rb_thread_local_aref ( VALUE  thread,
ID  key 
)

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.

Parameters
[in]threadThread that the target Fiber is running.
[in]keyThe name of the Fiber local storage to read.
Return values
RUBY_QnilNo such storage.
otherwiseThe value stored at key.
Note
There in fact are "true" thread local storage, but Ruby doesn't provide any interface of them to you, C programmers.

Definition at line 3571 of file thread.c.

◆ rb_thread_local_aset()

VALUE rb_thread_local_aset ( VALUE  thread,
ID  key,
VALUE  val 
)

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.

Parameters
[in]threadThread that the target Fiber is running.
[in]keyThe name of the Fiber local storage to write.
[in]valThe new value of the storage.
Exceptions
rb_eFrozenErrorthread is frozen.
Returns
The passed val as-is.
Postcondition
Fiber local storage key has value of val.
Note
There in fact are "true" thread local storage, but Ruby doesn't provide any interface of them to you, C programmers.

Definition at line 3719 of file thread.c.

Referenced by rb_detach_process().

◆ rb_thread_main()

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.

Returns
The main thread of the current ractor of the current execution context.
Precondition
This function must be called from a thread controlled by ruby.

Definition at line 3003 of file thread.c.

◆ rb_thread_run()

VALUE rb_thread_run ( VALUE  thread)

This is a rb_thread_wakeup() + rb_thread_schedule() combo.

Note
There is no guarantee that this function yields to the passed thread. It may still remain blocked on I/O.
Parameters
[out]threadThread in question to wake up.
Exceptions
rb_eThreadErrorStop flogging a dead horse.
Returns
The passed thread.

Definition at line 2906 of file thread.c.

◆ rb_thread_schedule()

void rb_thread_schedule ( void  )

Tries to switch to another thread.

This function blocks until the current thread re-acquires the GVL.

Exceptions
rb_eInterruptOperation interrupted.

Definition at line 1480 of file thread.c.

Referenced by rb_thread_run().

◆ rb_thread_sleep()

void rb_thread_sleep ( int  sec)

Blocks for the given period of time.

Warning
This function can be interrupted by signals.
Parameters
[in]secDuration in seconds.
Exceptions
rb_eInterruptInterrupted.

Definition at line 1455 of file thread.c.

◆ rb_thread_sleep_deadly()

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.

Exceptions
rb_eInterruptInterrupted.

Definition at line 1386 of file thread.c.

Referenced by rb_thread_stop().

◆ rb_thread_sleep_forever()

void rb_thread_sleep_forever ( void  )

Blocks indefinitely.

Exceptions
rb_eInterruptInterrupted.

Definition at line 1379 of file thread.c.

Referenced by rb_thread_fd_select().

◆ rb_thread_stop()

VALUE rb_thread_stop ( void  )

Stops the current thread.

This is not the end of the thread's lifecycle. A stopped thread can later be woken up.

Exceptions
rb_eThreadErrorStopping this thread would deadlock.
Return values
RUBY_QnilAlways.

Definition at line 2915 of file thread.c.

◆ rb_thread_wait_fd()

int rb_thread_wait_fd ( int  fd)

Blocks the current thread until the given file descriptor is ready to be read.

Parameters
[in]fdA file descriptor.
Exceptions
rb_eIOErrorClosed stream.
rb_eSystemCallErrorSituations like EBADF.

Definition at line 1591 of file io.c.

◆ rb_thread_wait_for()

void rb_thread_wait_for ( struct timeval  time)

Identical to rb_thread_sleep(), except it takes struct timeval instead.

Warning
This function can be interrupted by signals.
Parameters
[in]timeDuration.
Exceptions
rb_eInterruptInterrupted.

Definition at line 1411 of file thread.c.

Referenced by rb_thread_fd_select(), and rb_thread_sleep().

◆ rb_thread_wakeup()

VALUE rb_thread_wakeup ( VALUE  thread)

Marks a given thread as eligible for scheduling.

Note
It may still remain blocked on I/O.
This does not invoke the scheduler itself.
Parameters
[out]threadThread in question to wake up.
Exceptions
rb_eThreadErrorStop flogging a dead horse.
Returns
The passed thread.
Postcondition
The passed thread is made runnable.

Definition at line 2859 of file thread.c.

Referenced by rb_thread_run().

◆ rb_thread_wakeup_alive()

VALUE rb_thread_wakeup_alive ( VALUE  thread)

Identical to rb_thread_wakeup(), except it doesn't raise on an already killed thread.

Parameters
[out]threadA thread to wake up.
Return values
RUBY_Qnilthread is already killed.
otherwisethread is alive.
Postcondition
The passed thread is made runnable, unless killed.

Definition at line 2868 of file thread.c.

Referenced by rb_thread_wakeup().