Ruby: include/ruby/internal/intern/thread.h File Reference

Ruby 3.2.5p208 (2024-07-26 revision 31d0f1a2e7dbfb60731d1f05b868e1d578cda493)

Macros | Typedefs | Functions
thread.h File Reference

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.
#define | RUBY_UBF_PROCESS RBIMPL_CAST((rb_unblock_function_t *)-1)
| A special UBF for blocking process operations.

## Typedefs
typedef void | rb_unblock_function_t(void *)
| This is the type of UBFs.

## Functions
void | rb_thread_schedule (void)
| Tries to switch to another thread.
int | rb_thread_wait_fd (int fd)
| Blocks the current thread until the given file descriptor is ready to be read.
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.
void | rb_thread_fd_close (int fd)
| Notifies a closing of a file descriptor to other threads.
int | rb_thread_alone (void)
| Checks if the thread this function is running is the only thread that is currently alive.
void | rb_thread_sleep (int sec)
| Blocks for the given period of time.
void | rb_thread_sleep_forever (void)
| Blocks indefinitely.
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.
VALUE | rb_thread_stop (void)
| Stops the current thread.
VALUE | rb_thread_wakeup (VALUE thread)
| Marks a given thread as eligible for scheduling.
VALUE | rb_thread_wakeup_alive (VALUE thread)
| Identical to rb_thread_wakeup(), except it doesn't raise on an already killed thread.
VALUE | rb_thread_run (VALUE thread)
| This is a rb_thread_wakeup() + rb_thread_schedule() combo.
VALUE | rb_thread_kill (VALUE thread)
| Terminates the given thread.
VALUE | rb_thread_create (VALUE(*f)(void *g), void *g)
| Creates a Ruby thread that is backended by a C function.
void | rb_thread_wait_for (struct timeval time)
| Identical to rb_thread_sleep(), except it takes struct `timeval` instead.
VALUE | rb_thread_current (void)
| Obtains the "current" thread.
VALUE | rb_thread_main (void)
| Obtains the "main" thread.
VALUE | rb_thread_local_aref (VALUE thread, ID key)
| This badly named function reads from a Fiber local storage.
VALUE | rb_thread_local_aset (VALUE thread, ID key, VALUE val)
| This badly named function writes to a Fiber local storage.
void | rb_thread_atfork (void)
| A `pthread_atfork(3posix)`-like API.
void | rb_thread_atfork_before_exec (void)
| :FIXME: situation of this function is unclear.
VALUE | rb_exec_recursive (VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h)
| "Recursion" API entry point.
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`.
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.
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`.
void | rb_thread_check_ints (void)
| Checks for interrupts.
int | rb_thread_interrupted (VALUE thval)
| Checks if the thread's execution was recently interrupted.
VALUE | rb_mutex_new (void)
| Creates a mutex.
VALUE | rb_mutex_locked_p (VALUE mutex)
| Queries if there are any threads that holds the lock.
VALUE | rb_mutex_trylock (VALUE mutex)
| Attempts to lock the mutex, without waiting for other threads to unlock it.
VALUE | rb_mutex_lock (VALUE mutex)
| Attempts to lock the mutex.
VALUE | rb_mutex_unlock (VALUE mutex)
| Releases the mutex.
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.
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.

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

Copyright
  This file is a part of the programming language Ruby. Permission is hereby granted, to either redistribute and/or modify this file, provided that the conditions mentioned in the file COPYING are met. Consult the file for details.

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.

Referenced by rb_nogvl().

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

Referenced by rb_nogvl().

## 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(* | f )(VALUE g, VALUE h, int r),
|  | 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] | f | The function that possibly recurs.
  [in,out] | g | Passed as-is to `f`.
  [in,out] | h | Passed as-is to `f`.

Returns
  The return value of f.

Definition at line 5237 of file thread.c.

Referenced by rb_error_frozen_object(), rb_exec_recursive(), and rb_io_puts().

## ◆ rb_exec_recursive_outer()

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.

Inner recursions yield calls to rb_throw_obj().

Parameters

  [in] | f | The function that possibly recurs.
  [in,out] | g | Passed as-is to `f`.
  [in,out] | h | Passed as-is to `f`.

Returns
  The return value of f.

Definition at line 5260 of file thread.c.

Referenced by rb_exec_recursive_outer().

## ◆ rb_exec_recursive_paired()

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

Parameters

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

Definition at line 5248 of file thread.c.

Referenced by rb_ary_cmp(), rb_exec_recursive_paired(), and rb_num_coerce_bit().

## ◆ rb_exec_recursive_paired_outer()

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

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

Definition at line 5278 of file thread.c.

Referenced by rb_exec_recursive_paired_outer().

## ◆ rb_mutex_lock()

VALUE rb_mutex_lock | ( | VALUE | mutex | ) |

Attempts to lock the mutex.

It waits until the mutex gets available.

Parameters

  [out] | mutex | The mutex to lock.

Exceptions

  rb_eThreadError | Recursive deadlock situation.

Returns
  The passed mutex.

Postcondition
  The mutex is owned by the current thread.

Definition at line 415 of file thread_sync.c.

Referenced by rb_mutex_lock(), and 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] | mutex | The mutex in question.

Return values

  RUBY_Qtrue | The mutex is locked by someone.
  RUBY_Qfalse | The mutex is not locked by anyone.

Definition at line 200 of file thread_sync.c.

Referenced by rb_mutex_locked_p().

## ◆ rb_mutex_new()

VALUE rb_mutex_new | ( | void |  | ) |

Creates a mutex.

Returns
  An allocated instance of rb_cMutex.

Definition at line 188 of file thread_sync.c.

Referenced by rb_mutex_new().

## ◆ 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] | self | The target mutex.
  [in] | timeout | Duration, in seconds, in rb_cNumeric.

Exceptions

  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.

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 550 of file thread_sync.c.

Referenced by rb_mutex_sleep().

## ◆ rb_mutex_synchronize()

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.

Parameters

  [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 617 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] | mutex | The mutex to lock.

Return values

  RUBY_Qtrue | Successfully locked by the current thread.
  RUBY_Qfalse | Otherwise.

Note
  This function also returns RUBY_Qfalse when the mutex is already owned by the calling thread itself.

Definition at line 249 of file thread_sync.c.

Referenced by rb_mutex_trylock().

## ◆ rb_mutex_unlock()

VALUE rb_mutex_unlock | ( | VALUE | mutex | ) |

Releases the mutex.

Parameters

  [out] | mutex | The mutex to unlock.

Exceptions

  rb_eThreadError | The 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 488 of file thread_sync.c.

Referenced by rb_mutex_sleep(), rb_mutex_synchronize(), and rb_mutex_unlock().

## ◆ 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

  1 | Yes it is.
  0 | No it isn't.

Definition at line 3669 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 4703 of file thread.c.

Referenced by rb_thread_atfork().

## ◆ 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 4708 of file thread.c.

Referenced by rb_thread_atfork_before_exec().

## ◆ 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 1440 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(* | f )(void *g),
|  | void * | g )

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

Parameters

  [in] | f | The function to run on a thread.
  [in,out] | g | Passed through to `f`.

Exceptions

  rb_eThreadError | Could not create a ruby thread.
  rb_eSystemCallError | Situations like `EPERM`.

Returns
  Allocated instance of rb_cThread.

Note
  This doesn't wait for anything.

Definition at line 993 of file thread.c.

## ◆ 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 2808 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] | fd | A file descriptor.

Note
  This function blocks until all the threads waiting for such fd have woken up.

Definition at line 2530 of file thread.c.

Referenced by rb_thread_fd_close().

## ◆ 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] | fd | A file descriptor.

Exceptions

  rb_eIOError | Closed stream.
  rb_eSystemCallError | Situations like EBADF.

Definition at line 1570 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] | thval | Thread in question.

Return values

  0 | The thread was not interrupted.
  otherwise | The thread was interrupted recently.

Definition at line 1457 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] | thread | The thread to terminate.

Exceptions

  rb_eFatal | The passed thread is the running thread.
  rb_eSystemExit | The passed thread is the last thread.

Returns
  The passed thread.

Postcondition
  Either the passed thread, or the process entirely, is killed.

Definition at line 2590 of file thread.c.

Referenced by rb_nogvl().

## ◆ 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] | thread | Thread that the target Fiber is running.
  [in] | key | The name of the Fiber local storage to read.

Return values

  RUBY_Qnil | No such storage.
  otherwise | The 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 3397 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] | 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.

Exceptions

  rb_eFrozenError | `thread` 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 3545 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 2829 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] | thread | Thread in question to wake up.

Exceptions

  rb_eThreadError | Stop flogging a dead horse.

Returns
  The passed thread.

Definition at line 2732 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_eInterrupt | Operation interrupted.

Definition at line 1488 of file thread.c.

Referenced by rb_thread_fd_close(), and 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] | sec | Duration in seconds.

Exceptions

  rb_eInterrupt | Interrupted.

Definition at line 1463 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_eInterrupt | Interrupted.

Definition at line 1388 of file thread.c.

Referenced by rb_thread_stop().

## ◆ rb_thread_sleep_forever()

void rb_thread_sleep_forever | ( | void |  | ) |

Blocks indefinitely.

Exceptions

  rb_eInterrupt | Interrupted.

Definition at line 1381 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_eThreadError | Stopping this thread would deadlock.

Return values

  RUBY_Qnil | Always.

Definition at line 2741 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] | fd | A file descriptor.

Exceptions

  rb_eIOError | Closed stream.
  rb_eSystemCallError | Situations like EBADF.

Definition at line 1564 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] | time | Duration.

Exceptions

  rb_eInterrupt | Interrupted.

Definition at line 1425 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] | thread | Thread in question to wake up.

Exceptions

  rb_eThreadError | Stop flogging a dead horse.

Returns
  The passed thread.

Postcondition
  The passed thread is made runnable.

Definition at line 2685 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] | thread | A thread to wake up.

Return values

  RUBY_Qnil | `thread` is already killed.
  otherwise | `thread` is alive.

Postcondition
  The passed thread is made runnable, unless killed.

Definition at line 2694 of file thread.c.

Referenced by rb_thread_wakeup().