ruby-changes:67789
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:02:01 +0900 (JST)
Subject: [ruby-changes:67789] 0f3ae58882 (master): include/ruby/internal/intern/cont.h: add doxygen
https://git.ruby-lang.org/ruby.git/commit/?id=0f3ae58882 From 0f3ae588822fb63435d38b91001afd0237900fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= <shyouhei@r...> Date: Thu, 13 May 2021 09:49:20 +0900 Subject: include/ruby/internal/intern/cont.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/internal/intern/cont.h | 204 +++++++++++++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 3 deletions(-) diff --git a/include/ruby/internal/intern/cont.h b/include/ruby/internal/intern/cont.h index ebecbfb..e1e13f6 100644 --- a/include/ruby/internal/intern/cont.h +++ b/include/ruby/internal/intern/cont.h @@ -27,18 +27,216 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/intern/cont.h#L27 RBIMPL_SYMBOL_EXPORT_BEGIN() /* cont.c */ -VALUE rb_fiber_new(rb_block_call_func_t, VALUE); + +/** + * Creates a Fiber instance from a C-backended block. + * + * @param[in] func A function, to become the fiber's body. + * @param[in] callback_obj Passed as-is to `func`. + * @return An allocated new instance of rb_cFiber, which is ready to be + * "resume"d. + */ +VALUE rb_fiber_new(rb_block_call_func_t func, VALUE callback_obj); + +/** + * Queries the fiber which is calling this function. Any ruby execution + * context has its fiber, either explicitly or implicitly. + * + * @return The current fiber. + */ VALUE rb_fiber_current(void); -VALUE rb_fiber_alive_p(VALUE); -VALUE rb_obj_is_fiber(VALUE); +/** + * Queries the liveness of the passed fiber. "Alive" in this context means + * that the fiber can still be resumed. Once it reaches is its end of + * execution, this function returns ::RUBY_Qfalse. + * + * @param[in] fiber A target fiber. + * @retval RUBY_Qtrue It is. + * @retval RUBY_Qfalse It isn't. + */ +VALUE rb_fiber_alive_p(VALUE fiber); + +/** + * Queries if an object is a fiber. + * + * @param[in] obj Arbitrary ruby object. + * @retval RUBY_Qtrue It is. + * @retval RUBY_Qfalse It isn't. + */ +VALUE rb_obj_is_fiber(VALUE obj); + +/** + * Resumes the execution of the passed fiber, either from the point at which + * the last rb_fiber_yield() was called if any, or at the beginning of the + * fiber body if it is the first call to this function. + * + * Other arguments are passed into the fiber's body, either as return values of + * rb_fiber_yield() in case it switches to there, or as the block parameter of + * the fiber body if it switches to the beginning of the fiber. + * + * The return value of this function is either the value passed to previous + * rb_fiber_yield() call, or the ultimate evaluated value of the entire fiber + * body if the execution reaches the end of it. + * + * When an exception happens inside of a fiber it propagates to this function. + * + * ```ruby + * f = Fiber.new do |i| + * puts "<x> =>> #{i}" + * puts "<y> <-- #{i + 1}" + * j = Fiber.yield(i + 1) + * puts "<z> =>> #{j}" + * puts "<w> <-- #{j + 1}" + * next j + 1 + * end + * + * puts "[a] <-- 1" + * p = f.resume(1) + * puts "[b] =>> #{p}" + * puts "[c] <-- #{p + 1}" + * q = f.resume(p + 1) + * puts "[d] =>> #{q}" + * ``` + * + * Above program executes in `[a] <x> <y> [b] [c] <z> <w> [d]`. + * + * @param[out] fiber The fiber to resume. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Passed (somehow) to `fiber`. + * @exception rb_eFiberError `fib` is terminated etc. + * @exception rb_eException Any exceptions happen in `fiber`. + * @return (See above) + * @note This function _does_ return. + * + * @internal + * + * @shyouhei expected this function to raise ::rb_eFrozenError for frozen + * fibers but it doesn't in practice. Intentional or ...? + */ VALUE rb_fiber_resume(VALUE fiber, int argc, const VALUE *argv); + +/** + * Identical to rb_fiber_resume(), except you can specify how to handle the + * last element of the given array. + * + * @param[out] fiber The fiber to resume. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Passed (somehow) to `fiber`. + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `argv`'s last is not a keyword argument. + * - RB_PASS_KEYWORDS `argv`'s last is a keyword argument. + * - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block. + * @exception rb_eFiberError `fiber` is terminated etc. + * @exception rb_eException Any exceptions happen in `fiber`. + * @return Either what was yielded or the last value of the fiber body. + */ VALUE rb_fiber_resume_kw(VALUE fiber, int argc, const VALUE *argv, int kw_splat); +/** + * Yields the control back to the point where the current fiber was resumed. + * The passed objects would be the return value of rb_fiber_resume(). This + * fiber then suspends its execution until next time it is resumed. + * + * This function can also raise arbitrary exceptions injected from outside of + * the fiber, using `Fiber#raise` Ruby level API. There is no way to do that + * from C though. + * + * ```ruby + * exc = Class.new Exception + * + * f = Fiber.new do + * Fiber.yield + * rescue exc => e + * puts e.message + * end + * + * f.resume + * f.raise exc, "Hi!" + * ``` + * + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Passed to rb_fiber_resume(). + * @exception rb_eException (See above) + * @return (See rb_fiber_resume() for details) + * + * @internal + * + * "There is no way to do that from C" is a lie. But @shyouhei doesn't think + * this very intentionally obfuscated way to raise arbitrary exceptions from C + * is an official C API. Extension libraries must not know this fact. + */ VALUE rb_fiber_yield(int argc, const VALUE *argv); + +/** + * Identical to rb_fiber_yield(), except you can specify how to handle the last + * element of the given array. + * + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Passed to rb_fiber_resume(). + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `argv`'s last is not a keyword argument. + * - RB_PASS_KEYWORDS `argv`'s last is a keyword argument. + * - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block. + * @exception rb_eException What was raised using `Fiber#raise`. + * @return (See rb_fiber_resume() for details) + */ VALUE rb_fiber_yield_kw(int argc, const VALUE *argv, int kw_splat); +/** + * Transfers control to another fiber, resuming it from where it last stopped + * or starting it if it was not resumed before. The calling fiber will be + * suspended much like in a call to rb_fiber_yield(). + * + * The fiber which receives the transfer call treats it much like a resume + * call. Arguments passed to transfer are treated like those passed to resume. + * + * The two style of control passing to and from fiber (one is rb_fiber_resume() + * and rb_fiber_yield(), another is rb_fiber_transfer() to and from fiber) + * can't be freely mixed. + * + * - If the Fiber's lifecycle had started with transfer, it will never be + * able to yield or be resumed control passing, only finish or transfer + * back. (It still can resume other fibers that are allowed to be + * resumed.) + * + * - If the Fiber's lifecycle had started with resume, it can yield or + * transfer to another Fiber, but can receive control back only the way + * compatible with the way it was given away: if it had transferred, it + * only can be transferred back, and if it had yielded, it only can be + * resumed back. After that, it again can transfer or yield. + * + * If those rules are broken, rb_eFiberError is raised. + * + * For an individual Fiber design, yield/resume is easier to use (the Fiber + * just gives away control, it doesn't need to think about who the control is + * given to), while transfer is more flexible for complex cases, allowing to + * build arbitrary graphs of Fibers dependent on each other. + * + * @param[out] fiber Explicit control destination. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Passed to rb_fiber_resume(). + * @exception rb_eFiberError (See above) + * @exception rb_eException What was raised using `Fiber#raise`. + * @return (See rb_fiber_resume() for details) + */ VALUE rb_fiber_transfer(VALUE fiber, int argc, const VALUE *argv); + +/** + * Identical to rb_fiber_transfer(), except you can specify how to handle the + * last element of the given array. + * + * @param[out] fiber Explicit control destination. + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Passed to rb_fiber_resume(). + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `argv`'s last is not a keyword argument. + * - RB_PASS_KEYWORDS `argv`'s last is a keyword argument. + * - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block. + * @exception rb_eFiberError (See above) + * @exception rb_eException What was raised using `Fiber#raise`. + * @return (See rb_fiber_resume() for details) + */ VALUE rb_fiber_transfer_kw(VALUE fiber, int argc, const VALUE *argv, int kw_splat); RBIMPL_SYMBOL_EXPORT_END() -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/