* cont.c: rdoc for Fiber. patch by Muhammad Ali.

[ruby-core:20894]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21077 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
yugui 2008-12-27 00:25:47 +00:00
Родитель 2d5061bd98
Коммит 5736312715
2 изменённых файлов: 124 добавлений и 0 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Sat Dec 27 09:14:17 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
* cont.c: rdoc for Fiber. patch by Muhammad Ali.
[ruby-core:20894]
Sat Dec 27 05:38:59 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* process.c (after_fork): ignores a termination request in the

119
cont.c
Просмотреть файл

@ -570,6 +570,68 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
/* fiber */
/*********/
/*
* Document-class: Fiber
*
* Fibers are primitives for implementing light weight cooperative
* concurrency in Ruby. Basically they are a means of creating code blocks
* that can be paused and resumed, much like threads. The main difference
* is that they are never preempted and that the scheduling must be done by
* the programmer and not the VM.
*
* As opposed to other stackless light weight concurrency models, each fiber
* comes with a small 4KB stack. This enables the fiber to be paused from deeply
* nested function calls within the fiber block.
*
* When a fiber is created it will not run automatically. Rather it must be
* be explicitly asked to run using the <code>Fiber#resume</code> method.
* The code running inside the fiber can give up control by calling
* <code>Fiber.yield</code> in which case it yields control back to caller
* (the caller of the <code>Fiber#resume</code>).
*
* Upon yielding or termination the Fiber returns the value of the last
* executed expression
*
* For instance:
*
* fiber = Fiber.new do
* Fiber.yield 1
* 2
* end
*
* puts fiber.resume
* puts fiber.resume
* puts fiber.resume
*
* <em>produces</em>
*
* 1
* 2
* FiberError: dead fiber called
*
* The <code>Fiber#resume</code> method accepts an arbitary number of
* parameters, if it is the first call to <code>resume</code> then they
* will be passed as block arguments. Other wise they will be the return
* value of the call to <code>Fiber.yield</code>
*
* Example:
*
* fiber = Fiber.new do |first|
* second = Fiber.yield first + 2
* end
*
* puts fiber.resume 10
* puts fiber.resume 14
* puts fiber.resume 18
*
* <em>produces</em>
*
* 12
* 14
* FiberError: dead fiber called
*
*/
#define FIBER_VM_STACK_SIZE (4 * 1024)
static VALUE
@ -840,6 +902,14 @@ rb_fiber_yield(int argc, VALUE *argv)
return rb_fiber_transfer(return_fiber(), argc, argv);
}
/*
* call-seq:
* fiber.alive? -> true or false
*
* Returns true if the fiber can still be resumed (or transferred to).
* After finishing execution of the fiber block this method will always
* return false.
*/
VALUE
rb_fiber_alive_p(VALUE fibval)
{
@ -848,24 +918,73 @@ rb_fiber_alive_p(VALUE fibval)
return fib->status != TERMINATED;
}
/*
* call-seq:
* fiber.resume(args, ...) -> obj
*
* Resumes the fiber from the point at which the last <code>Fiber.yield</code>
* was called, or starts running it if it is the first call to
* <code>resume</code>. Arguments passed to resume will be the value of
* the <code>Fiber.yield</code> expression or will be passed as block
* parameters to the fiber's block if this is the first <code>resume</code>.
*
* Alternatively, when resume is called it evaluates to the arguments passed
* to the next <code>Fiber.yield</code> statement inside the fiber's block
* or to the block value if it runs to completion without any
* <code>Fiber.yield</code>
*/
static VALUE
rb_fiber_m_resume(int argc, VALUE *argv, VALUE fib)
{
return rb_fiber_resume(fib, argc, argv);
}
/*
* call-seq:
* fiber.transfer(args, ...) -> obj
*
* Transfer 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 <code>Fiber.yield</code>.
*
* The fiber which recieves the transfer call is treats it much like
* a resume call. Arguments passed to transfer are treated like those
* passed to resume.
*
* You cannot resume a fiber that transferred control to another one.
* This will cause a double resume error. You need to transfer control
* back to this fiber before it can yield and resume.
*/
static VALUE
rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fib)
{
return rb_fiber_transfer(fib, argc, argv);
}
/*
* call-seq:
* Fiber.yield(args, ...) -> obj
*
* Yields control back to the context that resumed the fiber, passing
* along any arguments that were passed to it. The fiber will resume
* processing at this point when <code>resume</code> is called next.
* Any arguments passed to the next <code>resume</code> will be the
* value that this <code>Fiber.yield</code> expression evaluates to.
*/
static VALUE
rb_fiber_s_yield(int argc, VALUE *argv, VALUE klass)
{
return rb_fiber_yield(argc, argv);
}
/*
* call-seq:
* Fiber.current() -> fiber
*
* Returns the current fiber. You need to <code>require 'fiber'</code>
* before using this method. If you are not running in the context of
* a fiber this method will return the root fiber.
*/
static VALUE
rb_fiber_s_current(VALUE klass)
{