summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber
diff options
context:
space:
mode:
Diffstat (limited to 'web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber')
-rw-r--r--web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/mrbgem.rake5
-rw-r--r--web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/src/fiber.c420
-rw-r--r--web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/test/fiber.rb208
3 files changed, 0 insertions, 633 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/mrbgem.rake
deleted file mode 100644
index 815cd3c4b..000000000
--- a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/mrbgem.rake
+++ /dev/null
@@ -1,5 +0,0 @@
-MRuby::Gem::Specification.new('mruby-fiber') do |spec|
- spec.license = 'MIT'
- spec.author = 'mruby developers'
- spec.summary = 'Fiber class'
-end
diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/src/fiber.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/src/fiber.c
deleted file mode 100644
index 9de175f34..000000000
--- a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/src/fiber.c
+++ /dev/null
@@ -1,420 +0,0 @@
-#include <mruby.h>
-#include <mruby/array.h>
-#include <mruby/class.h>
-#include <mruby/proc.h>
-
-#define fiber_ptr(o) ((struct RFiber*)mrb_ptr(o))
-
-#define FIBER_STACK_INIT_SIZE 64
-#define FIBER_CI_INIT_SIZE 8
-#define CI_ACC_RESUMED -3
-
-/*
- * call-seq:
- * Fiber.new{...} -> obj
- *
- * Creates a fiber, whose execution is suspend until it is explicitly
- * resumed using <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
- * resuming dead fiber (FiberError)
- *
- * The <code>Fiber#resume</code> method accepts an arbitrary number of
- * parameters, if it is the first call to <code>resume</code> then they
- * will be passed as block arguments. Otherwise 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
- * resuming dead fiber (FiberError)
- *
- */
-static mrb_value
-fiber_init(mrb_state *mrb, mrb_value self)
-{
- static const struct mrb_context mrb_context_zero = { 0 };
- struct RFiber *f = fiber_ptr(self);
- struct mrb_context *c;
- struct RProc *p;
- mrb_callinfo *ci;
- mrb_value blk;
- size_t slen;
-
- mrb_get_args(mrb, "&", &blk);
-
- if (f->cxt) {
- mrb_raise(mrb, E_RUNTIME_ERROR, "cannot initialize twice");
- }
- if (mrb_nil_p(blk)) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block");
- }
- p = mrb_proc_ptr(blk);
- if (MRB_PROC_CFUNC_P(p)) {
- mrb_raise(mrb, E_FIBER_ERROR, "tried to create Fiber from C defined method");
- }
-
- c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
- *c = mrb_context_zero;
- f->cxt = c;
-
- /* initialize VM stack */
- slen = FIBER_STACK_INIT_SIZE;
- if (p->body.irep->nregs > slen) {
- slen += p->body.irep->nregs;
- }
- c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value));
- c->stend = c->stbase + slen;
- c->stack = c->stbase;
-
-#ifdef MRB_NAN_BOXING
- {
- mrb_value *p = c->stbase;
- mrb_value *pend = c->stend;
-
- while (p < pend) {
- SET_NIL_VALUE(*p);
- p++;
- }
- }
-#else
- memset(c->stbase, 0, slen * sizeof(mrb_value));
-#endif
-
- /* copy receiver from a block */
- c->stack[0] = mrb->c->stack[0];
-
- /* initialize callinfo stack */
- c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo));
- c->ciend = c->cibase + FIBER_CI_INIT_SIZE;
- c->ci = c->cibase;
- c->ci->stackent = c->stack;
-
- /* adjust return callinfo */
- ci = c->ci;
- ci->target_class = p->target_class;
- ci->proc = p;
- mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p);
- ci->pc = p->body.irep->iseq;
- ci->nregs = p->body.irep->nregs;
- ci[1] = ci[0];
- c->ci++; /* push dummy callinfo */
-
- c->fib = f;
- c->status = MRB_FIBER_CREATED;
-
- return self;
-}
-
-static struct mrb_context*
-fiber_check(mrb_state *mrb, mrb_value fib)
-{
- struct RFiber *f = fiber_ptr(fib);
-
- mrb_assert(f->tt == MRB_TT_FIBER);
- if (!f->cxt) {
- mrb_raise(mrb, E_FIBER_ERROR, "uninitialized Fiber");
- }
- return f->cxt;
-}
-
-static mrb_value
-fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len)
-{
- if (len == 0) return mrb_nil_value();
- if (len == 1) return a[0];
- return mrb_ary_new_from_values(mrb, len, a);
-}
-
-/* mark return from context modifying method */
-#define MARK_CONTEXT_MODIFY(c) (c)->ci->target_class = NULL
-
-static void
-fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c)
-{
- mrb_callinfo *ci;
-
- for (ci = c->ci; ci >= c->cibase; ci--) {
- if (ci->acc < 0) {
- mrb_raise(mrb, E_FIBER_ERROR, "can't cross C function boundary");
- }
- }
-}
-
-static void
-fiber_switch_context(mrb_state *mrb, struct mrb_context *c)
-{
- if (mrb->c->fib) {
- mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib);
- }
- c->status = MRB_FIBER_RUNNING;
- mrb->c = c;
-}
-
-static mrb_value
-fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mrb_bool resume, mrb_bool vmexec)
-{
- struct mrb_context *c = fiber_check(mrb, self);
- struct mrb_context *old_c = mrb->c;
- mrb_value value;
-
- fiber_check_cfunc(mrb, c);
- if (resume && c->status == MRB_FIBER_TRANSFERRED) {
- mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber");
- }
- if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMED) {
- mrb_raise(mrb, E_FIBER_ERROR, "double resume (fib)");
- }
- if (c->status == MRB_FIBER_TERMINATED) {
- mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber");
- }
- mrb->c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED;
- c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c);
- if (c->status == MRB_FIBER_CREATED) {
- mrb_value *b, *e;
-
- if (len >= c->stend - c->stack) {
- mrb_raise(mrb, E_FIBER_ERROR, "too many arguments to fiber");
- }
- b = c->stack+1;
- e = b + len;
- while (b<e) {
- *b++ = *a++;
- }
- c->cibase->argc = len;
- value = c->stack[0] = c->ci->proc->env->stack[0];
- }
- else {
- value = fiber_result(mrb, a, len);
- }
- fiber_switch_context(mrb, c);
-
- if (vmexec) {
- c->vmexec = TRUE;
- value = mrb_vm_exec(mrb, c->ci[-1].proc, c->ci->pc);
- mrb->c = old_c;
- }
- else {
- MARK_CONTEXT_MODIFY(c);
- }
- return value;
-}
-
-/*
- * 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 mrb_value
-fiber_resume(mrb_state *mrb, mrb_value self)
-{
- mrb_value *a;
- mrb_int len;
- mrb_bool vmexec = FALSE;
-
- mrb_get_args(mrb, "*!", &a, &len);
- if (mrb->c->ci->acc < 0) {
- vmexec = TRUE;
- }
- return fiber_switch(mrb, self, len, a, TRUE, vmexec);
-}
-
-/* resume thread with given arguments */
-MRB_API mrb_value
-mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int len, const mrb_value *a)
-{
- return fiber_switch(mrb, fib, len, a, TRUE, TRUE);
-}
-
-/*
- * call-seq:
- * fiber.alive? -> true or false
- *
- * Returns true if the fiber can still be resumed. After finishing
- * execution of the fiber block this method will always return false.
- */
-static mrb_value
-fiber_alive_p(mrb_state *mrb, mrb_value self)
-{
- struct mrb_context *c = fiber_check(mrb, self);
- return mrb_bool_value(c->status != MRB_FIBER_TERMINATED);
-}
-
-static mrb_value
-fiber_eq(mrb_state *mrb, mrb_value self)
-{
- mrb_value other;
- mrb_get_args(mrb, "o", &other);
-
- if (mrb_type(other) != MRB_TT_FIBER) {
- return mrb_false_value();
- }
- return mrb_bool_value(fiber_ptr(self) == fiber_ptr(other));
-}
-
-/*
- * call-seq:
- * fiber.transfer(args, ...) -> obj
- *
- * Transfers control to receiver fiber of the method call.
- * Unlike <code>resume</code> the receiver wouldn't be pushed to call
- * stack of fibers. Instead it will switch to the call stack of
- * transferring fiber.
- * When resuming a fiber that was transferred to another fiber it would
- * cause double resume error. Though when the fiber is re-transferred
- * and <code>Fiber.yield</code> is called, the fiber would be resumable.
- */
-static mrb_value
-fiber_transfer(mrb_state *mrb, mrb_value self)
-{
- struct mrb_context *c = fiber_check(mrb, self);
- mrb_value* a;
- mrb_int len;
-
- fiber_check_cfunc(mrb, mrb->c);
- mrb_get_args(mrb, "*!", &a, &len);
-
- if (c == mrb->root_c) {
- mrb->c->status = MRB_FIBER_TRANSFERRED;
- fiber_switch_context(mrb, c);
- MARK_CONTEXT_MODIFY(c);
- return fiber_result(mrb, a, len);
- }
-
- if (c == mrb->c) {
- return fiber_result(mrb, a, len);
- }
-
- return fiber_switch(mrb, self, len, a, FALSE, FALSE);
-}
-
-/* yield values to the caller fiber */
-/* mrb_fiber_yield() must be called as `return mrb_fiber_yield(...)` */
-MRB_API mrb_value
-mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a)
-{
- struct mrb_context *c = mrb->c;
-
- if (!c->prev) {
- mrb_raise(mrb, E_FIBER_ERROR, "can't yield from root fiber");
- }
-
- fiber_check_cfunc(mrb, c);
- c->prev->status = MRB_FIBER_RUNNING;
- c->status = MRB_FIBER_SUSPENDED;
- fiber_switch_context(mrb, c->prev);
- c->prev = NULL;
- if (c->vmexec) {
- c->vmexec = FALSE;
- mrb->c->ci->acc = CI_ACC_RESUMED;
- }
- MARK_CONTEXT_MODIFY(mrb->c);
- return fiber_result(mrb, a, len);
-}
-
-/*
- * 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
- *
- * mruby limitation: Fiber resume/yield cannot cross C function boundary.
- * thus you cannot yield from #initialize which is called by mrb_funcall().
- */
-static mrb_value
-fiber_yield(mrb_state *mrb, mrb_value self)
-{
- mrb_value *a;
- mrb_int len;
-
- mrb_get_args(mrb, "*!", &a, &len);
- return mrb_fiber_yield(mrb, len, a);
-}
-
-/*
- * call-seq:
- * Fiber.current() -> fiber
- *
- * Returns the current fiber. If you are not running in the context of
- * a fiber this method will return the root fiber.
- */
-static mrb_value
-fiber_current(mrb_state *mrb, mrb_value self)
-{
- if (!mrb->c->fib) {
- struct RFiber *f = (struct RFiber*)mrb_obj_alloc(mrb, MRB_TT_FIBER, mrb_class_ptr(self));
-
- f->cxt = mrb->c;
- mrb->c->fib = f;
- }
- return mrb_obj_value(mrb->c->fib);
-}
-
-void
-mrb_mruby_fiber_gem_init(mrb_state* mrb)
-{
- struct RClass *c;
-
- c = mrb_define_class(mrb, "Fiber", mrb->object_class);
- MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER);
-
- mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE());
- mrb_define_method(mrb, c, "resume", fiber_resume, MRB_ARGS_ANY());
- mrb_define_method(mrb, c, "transfer", fiber_transfer, MRB_ARGS_ANY());
- mrb_define_method(mrb, c, "alive?", fiber_alive_p, MRB_ARGS_NONE());
- mrb_define_method(mrb, c, "==", fiber_eq, MRB_ARGS_REQ(1));
-
- mrb_define_class_method(mrb, c, "yield", fiber_yield, MRB_ARGS_ANY());
- mrb_define_class_method(mrb, c, "current", fiber_current, MRB_ARGS_NONE());
-
- mrb_define_class(mrb, "FiberError", mrb->eStandardError_class);
-}
-
-void
-mrb_mruby_fiber_gem_final(mrb_state* mrb)
-{
-}
diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/test/fiber.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/test/fiber.rb
deleted file mode 100644
index d063a0a62..000000000
--- a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-fiber/test/fiber.rb
+++ /dev/null
@@ -1,208 +0,0 @@
-assert('Fiber.new') do
- f = Fiber.new{}
- assert_kind_of Fiber, f
-end
-
-assert('Fiber#resume') do
- f = Fiber.new{|x| x }
- assert_equal 2, f.resume(2)
-end
-
-assert('Fiber#transfer') do
- f2 = nil
- f1 = Fiber.new do |v|
- Fiber.yield v
- f2.transfer
- end
- f2 = Fiber.new do
- f1.transfer(1)
- f1.transfer(1)
- Fiber.yield 2
- end
- assert_equal 1, f2.resume
- assert_raise(FiberError) { f2.resume }
- assert_equal 2, f2.transfer
- assert_raise(FiberError) { f1.resume }
- f1.transfer
- f2.resume
- assert_false f1.alive?
- assert_false f2.alive?
-end
-
-assert('Fiber#alive?') do
- f = Fiber.new{ Fiber.yield }
- f.resume
- assert_true f.alive?
- f.resume
- assert_false f.alive?
-end
-
-assert('Fiber#==') do
- root = Fiber.current
- assert_equal root, root
- assert_equal root, Fiber.current
- assert_false root != Fiber.current
- f = Fiber.new {
- assert_false root == Fiber.current
- }
- f.resume
- assert_false f == root
- assert_true f != root
-end
-
-assert('Fiber.yield') do
- f = Fiber.new{|x| Fiber.yield x }
- assert_equal 3, f.resume(3)
- assert_true f.alive?
-end
-
-assert('FiberError') do
- assert_equal StandardError, FiberError.superclass
-end
-
-assert('Fiber iteration') do
- f1 = Fiber.new{
- [1,2,3].each{|x| Fiber.yield(x)}
- }
- f2 = Fiber.new{
- [9,8,7].each{|x| Fiber.yield(x)}
- }
- a = []
- 3.times {
- a << f1.resume
- a << f2.resume
- }
- assert_equal [1,9,2,8,3,7], a
-end
-
-assert('Fiber with splat in the block argument list') {
- Fiber.new{|*x|x}.resume(1) == [1]
-}
-
-assert('Fiber raises on resume when dead') do
- assert_raise(FiberError) do
- f = Fiber.new{}
- f.resume
- assert_false f.alive?
- f.resume
- end
-end
-
-assert('Yield raises when called on root fiber') do
- assert_raise(FiberError) { Fiber.yield }
-end
-
-assert('Double resume of Fiber') do
- f1 = Fiber.new {}
- f2 = Fiber.new {
- f1.resume
- assert_raise(FiberError) { f2.resume }
- Fiber.yield 0
- }
- assert_equal 0, f2.resume
- f2.resume
- assert_false f1.alive?
- assert_false f2.alive?
-end
-
-assert('Recursive resume of Fiber') do
- f1, f2 = nil, nil
- f1 = Fiber.new { assert_raise(FiberError) { f2.resume } }
- f2 = Fiber.new {
- f1.resume
- Fiber.yield 0
- }
- f3 = Fiber.new {
- f2.resume
- }
- assert_equal 0, f3.resume
- f2.resume
- assert_false f1.alive?
- assert_false f2.alive?
- assert_false f3.alive?
-end
-
-assert('Root fiber resume') do
- root = Fiber.current
- assert_raise(FiberError) { root.resume }
- f = Fiber.new {
- assert_raise(FiberError) { root.resume }
- }
- f.resume
- assert_false f.alive?
-end
-
-assert('Fiber without block') do
- assert_raise(ArgumentError) { Fiber.new }
-end
-
-
-assert('Transfer to self.') do
- result = []
- f = Fiber.new { result << :start; f.transfer; result << :end }
- f.transfer
- assert_equal [:start, :end], result
-
- result = []
- f = Fiber.new { result << :start; f.transfer; result << :end }
- f.resume
- assert_equal [:start, :end], result
-end
-
-assert('Resume transferred fiber') do
- f = Fiber.new {
- assert_raise(FiberError) { f.resume }
- }
- f.transfer
-end
-
-assert('Root fiber transfer.') do
- result = nil
- root = Fiber.current
- f = Fiber.new {
- result = :ok
- root.transfer
- }
- f.resume
- assert_true f.alive?
- assert_equal :ok, result
-end
-
-assert('Break nested fiber with root fiber transfer') do
- root = Fiber.current
-
- result = nil
- f2 = nil
- f1 = Fiber.new {
- Fiber.yield f2.resume
- result = :f1
- }
- f2 = Fiber.new {
- result = :to_root
- root.transfer :from_f2
- result = :f2
- }
- assert_equal :from_f2, f1.resume
- assert_equal :to_root, result
- assert_equal :f2, f2.transfer
- assert_equal :f2, result
- assert_false f2.alive?
- assert_equal :f1, f1.resume
- assert_equal :f1, result
- assert_false f1.alive?
-end
-
-assert('CRuby Fiber#transfer test.') do
- ary = []
- f2 = nil
- f1 = Fiber.new{
- ary << f2.transfer(:foo)
- :ok
- }
- f2 = Fiber.new{
- ary << f1.transfer(:baz)
- :ng
- }
- assert_equal :ok, f1.transfer
- assert_equal [:baz], ary
-end