зеркало из https://github.com/github/ruby.git
* cont.c: fix bug around Continuation and Fiber.
* test/ruby/test_continuation.rb: add tests for Continuation. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12401 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
d15b7d0509
Коммит
d64609463f
|
@ -1,3 +1,9 @@
|
||||||
|
Tue May 29 10:55:24 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* cont.c: fix bug around Continuation and Fiber.
|
||||||
|
|
||||||
|
* test/ruby/test_continuation.rb: add tests for Continuation.
|
||||||
|
|
||||||
Tue May 29 10:54:34 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Tue May 29 10:54:34 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* win32/win32.c (rb_w32_opendir, rb_w32_readdir): eliminate magic
|
* win32/win32.c (rb_w32_opendir, rb_w32_readdir): eliminate magic
|
||||||
|
|
6
cont.c
6
cont.c
|
@ -128,6 +128,7 @@ cont_capture(volatile int *stat)
|
||||||
|
|
||||||
cont->vm_stack = ALLOC_N(VALUE, th->stack_size);
|
cont->vm_stack = ALLOC_N(VALUE, th->stack_size);
|
||||||
MEMCPY(cont->vm_stack, th->stack, VALUE, th->stack_size);
|
MEMCPY(cont->vm_stack, th->stack, VALUE, th->stack_size);
|
||||||
|
th->stack = 0;
|
||||||
|
|
||||||
cont_save_machine_stack(th, cont);
|
cont_save_machine_stack(th, cont);
|
||||||
|
|
||||||
|
@ -157,10 +158,12 @@ cont_restore_1(rb_context_t *cont)
|
||||||
/* fiber */
|
/* fiber */
|
||||||
th->stack = sth->stack;
|
th->stack = sth->stack;
|
||||||
th->stack_size = sth->stack_size;
|
th->stack_size = sth->stack_size;
|
||||||
|
th->fiber = cont->self;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* continuation */
|
/* continuation */
|
||||||
MEMCPY(th->stack, cont->vm_stack, VALUE, sth->stack_size);
|
MEMCPY(th->stack, cont->vm_stack, VALUE, sth->stack_size);
|
||||||
|
th->fiber = sth->fiber;
|
||||||
}
|
}
|
||||||
|
|
||||||
th->cfp = sth->cfp;
|
th->cfp = sth->cfp;
|
||||||
|
@ -169,11 +172,10 @@ cont_restore_1(rb_context_t *cont)
|
||||||
th->state = sth->state;
|
th->state = sth->state;
|
||||||
th->status = sth->status;
|
th->status = sth->status;
|
||||||
th->tag = sth->tag;
|
th->tag = sth->tag;
|
||||||
|
th->trap_tag = sth->trap_tag;
|
||||||
th->errinfo = sth->errinfo;
|
th->errinfo = sth->errinfo;
|
||||||
th->first_proc = sth->first_proc;
|
th->first_proc = sth->first_proc;
|
||||||
|
|
||||||
th->fiber = cont->self;
|
|
||||||
|
|
||||||
/* restore machine stack */
|
/* restore machine stack */
|
||||||
if (cont->machine_stack_src) {
|
if (cont->machine_stack_src) {
|
||||||
MEMCPY(cont->machine_stack_src, cont->machine_stack,
|
MEMCPY(cont->machine_stack_src, cont->machine_stack,
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
class TestContinuation < Test::Unit::TestCase
|
||||||
|
def test_create
|
||||||
|
assert_equal(:ok, callcc{:ok})
|
||||||
|
assert_equal(:ok, callcc{|c| c.call :ok})
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_call
|
||||||
|
assert_equal(:ok, callcc{|c| c.call :ok})
|
||||||
|
|
||||||
|
ary = []
|
||||||
|
ary << callcc{|c|
|
||||||
|
@cont = c
|
||||||
|
:a
|
||||||
|
}
|
||||||
|
@cont.call :b if ary.length < 3
|
||||||
|
assert_equal([:a, :b, :b], ary)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_error
|
||||||
|
cont = callcc{|c| c}
|
||||||
|
assert_raise(RuntimeError){
|
||||||
|
Thread.new{cont.call}.join
|
||||||
|
}
|
||||||
|
assert_raise(LocalJumpError){
|
||||||
|
callcc
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Загрузка…
Ссылка в новой задаче