2021-07-09 02:35:21 -04:00
|
|
|
#ifndef RUBY_FIBER_SCHEDULER_H /*-*-C++-*-vi:se ft=cpp:*/
|
2021-02-09 01:39:56 -05:00
|
|
|
#define RUBY_FIBER_SCHEDULER_H
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @author Ruby developers <ruby-core@ruby-lang.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.
|
2021-07-09 02:35:21 -04:00
|
|
|
* @brief Scheduler APIs.
|
2021-02-09 01:39:56 -05:00
|
|
|
*/
|
2021-07-09 02:35:21 -04:00
|
|
|
#include "ruby/internal/config.h"
|
|
|
|
|
|
|
|
#ifdef STDC_HEADERS
|
|
|
|
#include <stddef.h> /* size_t */
|
|
|
|
#endif
|
|
|
|
|
2021-02-09 01:39:56 -05:00
|
|
|
#include "ruby/ruby.h"
|
2021-07-09 02:35:21 -04:00
|
|
|
#include "ruby/internal/dllexport.h"
|
2021-02-09 01:39:56 -05:00
|
|
|
|
2021-04-09 17:00:05 -04:00
|
|
|
RBIMPL_SYMBOL_EXPORT_BEGIN()
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
struct timeval;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Queries the current scheduler of the current thread that is calling this
|
|
|
|
* function.
|
|
|
|
*
|
|
|
|
* @retval RUBY_Qnil No scheduler has been set so far to this thread (which
|
|
|
|
* is the default).
|
|
|
|
* @retval otherwise The scheduler that was last set for the current thread
|
|
|
|
* with rb_fiber_scheduler_set().
|
|
|
|
*/
|
2021-02-09 03:11:14 -05:00
|
|
|
VALUE rb_fiber_scheduler_get(void);
|
2021-07-09 02:35:21 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructively assigns the passed scheduler to that of the current thread
|
|
|
|
* that is calling this function. If the scheduler is set, non-blocking fibers
|
|
|
|
* (created by `Fiber.new` with `blocking: false`, or by `Fiber.schedule`) call
|
|
|
|
* that scheduler's hook methods on potentially blocking operations, and the
|
|
|
|
* current thread will call scheduler's `#close` method on finalisation
|
|
|
|
* (allowing the scheduler to properly manage all non-finished fibers).
|
|
|
|
* `scheduler` can be an object of any class corresponding to
|
|
|
|
* `Fiber::SchedulerInterface`. Its implementation is up to the user.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler The scheduler to set.
|
|
|
|
* @exception rb_eArgError `scheduler` does not conform the interface.
|
|
|
|
* @post Current thread's scheduler is `scheduler`.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_set(VALUE scheduler);
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/**
|
|
|
|
* Identical to rb_fiber_scheduler_get(), except it also returns ::RUBY_Qnil in
|
|
|
|
* case of a blocking fiber. As blocking fibers do not participate schedulers'
|
|
|
|
* scheduling this function can be handy.
|
|
|
|
*
|
|
|
|
* @retval RUBY_Qnil No scheduler is in effect.
|
|
|
|
* @retval otherwise The scheduler that is in effect, if any.
|
|
|
|
*/
|
2021-02-09 03:11:14 -05:00
|
|
|
VALUE rb_fiber_scheduler_current(void);
|
2021-07-09 02:35:21 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Identical to rb_fiber_scheduler_current(), except it queries for that of the
|
|
|
|
* passed thread instead of the implicit current one.
|
|
|
|
*
|
|
|
|
* @param[in] thread Target thread.
|
|
|
|
* @exception rb_eTypeError `thread` is not a thread.
|
|
|
|
* @retval RUBY_Qnil No scheduler is in effect in `thread`.
|
|
|
|
* @retval otherwise The scheduler that is in effect in `thread`.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_current_for_thread(VALUE thread);
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/**
|
|
|
|
* Converts the passed timeout to an expression that rb_fiber_scheduler_block()
|
|
|
|
* etc. expects.
|
|
|
|
*
|
|
|
|
* @param[in] timeout A duration (can be `NULL`).
|
|
|
|
* @retval RUBY_Qnil No timeout (blocks indefinitely).
|
|
|
|
* @retval otherwise A timeout object.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_make_timeout(struct timeval *timeout);
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/**
|
|
|
|
* Closes the passed scheduler object. This expects the scheduler to wait for
|
|
|
|
* all fibers. Thus the scheduler's main loop tends to start here.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @return What `scheduler.close` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_close(VALUE scheduler);
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/**
|
|
|
|
* Nonblocking `sleep`. Depending on scheduler implementation, this for
|
|
|
|
* instance switches to another fiber etc.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] duration Passed as-is to `scheduler.kernel_sleep`.
|
|
|
|
* @return What `scheduler.kernel_sleep` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_kernel_sleep(VALUE scheduler, VALUE duration);
|
2021-07-09 02:35:21 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Identical to rb_fiber_scheduler_kernel_sleep(), except it can pass multiple
|
|
|
|
* arguments.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] argc Number of objects of `argv`.
|
|
|
|
* @param[in] argv Passed as-is to `scheduler.kernel_sleep`
|
|
|
|
* @return What `scheduler.kernel_sleep` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_kernel_sleepv(VALUE scheduler, int argc, VALUE * argv);
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/* Description TBW */
|
2021-03-30 00:33:15 -04:00
|
|
|
#if 0
|
|
|
|
VALUE rb_fiber_scheduler_timeout_after(VALUE scheduler, VALUE timeout, VALUE exception, VALUE message);
|
|
|
|
VALUE rb_fiber_scheduler_timeout_afterv(VALUE scheduler, int argc, VALUE * argv);
|
2021-07-09 02:35:21 -04:00
|
|
|
int rb_fiber_scheduler_supports_process_wait(VALUE scheduler);
|
2021-03-30 00:33:15 -04:00
|
|
|
#endif
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/**
|
|
|
|
* Nonblocking `waitpid`. Depending on scheduler implementation, this for
|
|
|
|
* instance switches to another fiber etc.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] pid Process ID to wait.
|
|
|
|
* @param[in] flags Wait flags, e.g. `WUNTRACED`.
|
|
|
|
* @return What `scheduler.process_wait` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags);
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/**
|
|
|
|
* Nonblocking wait for the passed "blocker", which is for instance
|
|
|
|
* `Thread.join` or `Mutex.lock`. Depending on scheduler implementation, this
|
|
|
|
* for instance switches to another fiber etc.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] blocker What blocks the current fiber.
|
|
|
|
* @param[in] timeout Numeric timeout.
|
|
|
|
* @return What `scheduler.block` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout);
|
2021-07-09 02:35:21 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Wakes up a fiber previously blocked using rb_fiber_scheduler_block().
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] blocker What was awaited for.
|
|
|
|
* @param[in] fiber What to unblock.
|
|
|
|
* @return What `scheduler.unblock` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber);
|
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/**
|
|
|
|
* Nonblocking version of rb_io_wait(). Depending on scheduler implementation,
|
|
|
|
* this for instance switches to another fiber etc.
|
|
|
|
*
|
|
|
|
* The "events" here is a Ruby level integer, which is an OR-ed value of
|
|
|
|
* `IO::READABLE`, `IO::WRITable`, and `IO::PRIORITY`.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] io An io object to wait.
|
|
|
|
* @param[in] events An integer set of interests.
|
|
|
|
* @param[in] timeout Numeric timeout.
|
|
|
|
* @return What `scheduler.io_wait` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout);
|
2021-07-09 02:35:21 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Nonblocking wait until the passed IO is ready for reading. This is a
|
|
|
|
* special case of rb_fiber_scheduler_io_wait(), where the interest is
|
|
|
|
* `IO::READABLE` and timeout is never.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] io An io object to wait.
|
|
|
|
* @return What `scheduler.io_wait` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_io_wait_readable(VALUE scheduler, VALUE io);
|
2021-07-09 02:35:21 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Nonblocking wait until the passed IO is ready for writing. This is a
|
|
|
|
* special case of rb_fiber_scheduler_io_wait(), where the interest is
|
|
|
|
* `IO::WRITABLE` and timeout is never.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] io An io object to wait.
|
|
|
|
* @return What `scheduler.io_wait` returns.
|
|
|
|
*/
|
2021-02-09 01:39:56 -05:00
|
|
|
VALUE rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io);
|
2021-07-09 02:35:21 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Nonblocking read from the passed IO.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[out] io An io object to read from.
|
|
|
|
* @param[out] buffer Return buffer.
|
|
|
|
* @param[in] length Requested number of bytes to read.
|
|
|
|
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
|
|
|
|
* @return otherwise What `scheduler.io_read` returns.
|
|
|
|
*/
|
2021-07-02 06:41:16 -04:00
|
|
|
VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t length);
|
2021-07-09 02:35:21 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Nonblocking write to the passed IO.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[out] io An io object to write to.
|
|
|
|
* @param[in] buffer What to write.
|
|
|
|
* @param[in] length Number of bytes to write.
|
|
|
|
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
|
|
|
|
* @return otherwise What `scheduler.io_write` returns.
|
|
|
|
*/
|
2021-07-02 06:41:16 -04:00
|
|
|
VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t length);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Nonblocking read from the passed IO using a native buffer.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[out] io An io object to read from.
|
|
|
|
* @param[out] buffer Return buffer.
|
|
|
|
* @param[in] length Requested number of bytes to read.
|
|
|
|
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
|
|
|
|
* @return otherwise What `scheduler.io_read` returns.
|
|
|
|
*/
|
|
|
|
VALUE rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *buffer, size_t size, size_t length);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Nonblocking write to the passed IO using a native buffer.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[out] io An io object to write to.
|
|
|
|
* @param[in] buffer What to write.
|
|
|
|
* @param[in] length Number of bytes to write.
|
|
|
|
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
|
|
|
|
* @return otherwise What `scheduler.io_write` returns.
|
|
|
|
*/
|
|
|
|
VALUE rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *buffer, size_t size, size_t length);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Nonblocking close the given IO.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] io An io object to close.
|
|
|
|
* @retval RUBY_Qundef `scheduler` doesn't have `#io_close`.
|
|
|
|
* @return otherwise What `scheduler.io_close` returns.
|
|
|
|
*/
|
|
|
|
VALUE rb_fiber_scheduler_io_close(VALUE scheduler, VALUE io);
|
2021-02-09 01:39:56 -05:00
|
|
|
|
2021-07-09 02:35:21 -04:00
|
|
|
/**
|
|
|
|
* Nonblocking DNS lookup.
|
|
|
|
*
|
|
|
|
* @param[in] scheduler Target scheduler.
|
|
|
|
* @param[in] hostname A host name to query.
|
|
|
|
* @retval RUBY_Qundef `scheduler` doesn't have `#address_resolve`.
|
|
|
|
* @return otherwise What `scheduler.address_resolve` returns.
|
|
|
|
*/
|
2021-06-14 00:21:08 -04:00
|
|
|
VALUE rb_fiber_scheduler_address_resolve(VALUE scheduler, VALUE hostname);
|
|
|
|
|
2021-04-09 17:00:05 -04:00
|
|
|
RBIMPL_SYMBOL_EXPORT_END()
|
|
|
|
|
2021-02-09 01:39:56 -05:00
|
|
|
#endif /* RUBY_FIBER_SCHEDULER_H */
|