summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-06-06 07:10:19 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-06-06 07:10:19 +0000
commite9c440815ef2db47854fe3a3e282e33d7d209c03 (patch)
treebb0dd7035f385e633be1943f56097724083688b7
parentb0c9215f72c571c095bf82c4233af6ff848d48d2 (diff)
revert r59023 because it contans unrelated developping code
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59024 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--test/ruby/test_io.rb22
-rw-r--r--thread.c2
-rw-r--r--vm.c27
-rw-r--r--vm_core.h1
4 files changed, 32 insertions, 20 deletions
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 2cd60a4fca..791e52b500 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -2823,6 +2823,28 @@ __END__
end;
end
+ def test_single_exception_on_close
+ a = []
+ t = []
+ 10.times do
+ r, w = IO.pipe
+ a << [r, w]
+ t << Thread.new do
+ while r.gets
+ end rescue IOError
+ Thread.current.pending_interrupt?
+ end
+ end
+ a.each do |r, w|
+ w.write -"\n"
+ w.close
+ r.close
+ end
+ t.each do |th|
+ assert_equal false, th.value, '[ruby-core:81581] [Bug #13632]'
+ end
+ end
+
def test_open_mode
feature4742 = "[ruby-core:36338]"
bug6055 = '[ruby-dev:45268]'
diff --git a/thread.c b/thread.c
index da834974bd..42159b3c19 100644
--- a/thread.c
+++ b/thread.c
@@ -2213,6 +2213,8 @@ rb_notify_fd_close(int fd)
if (wfd->fd == fd) {
rb_thread_t *th = wfd->th;
VALUE err = th->vm->special_exceptions[ruby_error_stream_closed];
+
+ wfd->fd = -1; /* ensure we only enqueue once */
rb_threadptr_pending_interrupt_enque(th, err);
rb_threadptr_interrupt(th);
busy = 1;
diff --git a/vm.c b/vm.c
index e2bb1d3ce2..33be0723fa 100644
--- a/vm.c
+++ b/vm.c
@@ -1004,11 +1004,11 @@ invoke_bmethod(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const struct
static inline VALUE
invoke_iseq_block_from_c(rb_thread_t *th, const struct rb_captured_block *captured,
VALUE self, int argc, const VALUE *argv, VALUE passed_block_handler,
- const rb_cref_t *cref, VALUE additional_type)
+ const rb_cref_t *cref, int is_lambda)
{
const rb_iseq_t *iseq = rb_iseq_check(captured->code.iseq);
int i, opt_pc;
- VALUE type = VM_FRAME_MAGIC_BLOCK | additional_type;
+ VALUE type = VM_FRAME_MAGIC_BLOCK | (is_lambda ? VM_FRAME_FLAG_LAMBDA : 0);
rb_control_frame_t *cfp = th->ec.cfp;
VALUE *sp = cfp->sp;
const rb_callable_method_entry_t *me = th->passed_bmethod_me;
@@ -1021,7 +1021,7 @@ invoke_iseq_block_from_c(rb_thread_t *th, const struct rb_captured_block *captur
}
opt_pc = vm_yield_setup_args(th, iseq, argc, sp, passed_block_handler,
- ((type & VM_FRAME_FLAG_LAMBDA) ? arg_setup_method : arg_setup_block));
+ (is_lambda ? arg_setup_method : arg_setup_block));
cfp->sp = sp;
if (me == NULL) {
@@ -1038,8 +1038,6 @@ invoke_block_from_c_bh(rb_thread_t *th, VALUE block_handler,
VALUE passed_block_handler, const rb_cref_t *cref,
int is_lambda, int force_blockarg)
{
- VALUE additional_type = is_lambda ? VM_FRAME_FLAG_LAMBDA : 0;
-
again:
switch (vm_block_handler_type(block_handler)) {
case block_handler_type_iseq:
@@ -1047,7 +1045,7 @@ invoke_block_from_c_bh(rb_thread_t *th, VALUE block_handler,
const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(block_handler);
return invoke_iseq_block_from_c(th, captured, captured->self,
argc, argv, passed_block_handler,
- cref, additional_type);
+ cref, is_lambda);
}
case block_handler_type_ifunc:
return vm_yield_with_cfunc(th, VM_BH_TO_IFUNC_BLOCK(block_handler),
@@ -1057,11 +1055,8 @@ invoke_block_from_c_bh(rb_thread_t *th, VALUE block_handler,
return vm_yield_with_symbol(th, VM_BH_TO_SYMBOL(block_handler),
argc, argv, passed_block_handler);
case block_handler_type_proc:
- if (force_blockarg == FALSE && block_proc_is_lambda(VM_BH_TO_PROC(block_handler))) {
- additional_type = VM_FRAME_FLAG_LAMBDA;
- }
- else {
- additional_type = VM_FRAME_FLAG_PROC;
+ if (force_blockarg == FALSE) {
+ is_lambda = block_proc_is_lambda(VM_BH_TO_PROC(block_handler));
}
block_handler = vm_proc_to_block_handler(VM_BH_TO_PROC(block_handler));
goto again;
@@ -1119,23 +1114,17 @@ invoke_block_from_c_proc(rb_thread_t *th, const rb_proc_t *proc,
VALUE passed_block_handler, int is_lambda)
{
const struct rb_block *block = &proc->block;
- VALUE additional_type = is_lambda ? VM_FRAME_FLAG_LAMBDA : VM_FRAME_FLAG_PROC;
again:
switch (vm_block_type(block)) {
case block_type_iseq:
- return invoke_iseq_block_from_c(th, &block->as.captured, self, argc, argv, passed_block_handler, NULL, additional_type);
+ return invoke_iseq_block_from_c(th, &block->as.captured, self, argc, argv, passed_block_handler, NULL, is_lambda);
case block_type_ifunc:
return vm_yield_with_cfunc(th, &block->as.captured, self, argc, argv, passed_block_handler);
case block_type_symbol:
return vm_yield_with_symbol(th, block->as.symbol, argc, argv, passed_block_handler);
case block_type_proc:
- if (block_proc_is_lambda(block->as.proc)) {
- additional_type = VM_FRAME_FLAG_LAMBDA;
- }
- else {
- additional_type = VM_FRAME_FLAG_PROC;
- }
+ is_lambda = block_proc_is_lambda(block->as.proc);
block = vm_proc_block(block->as.proc);
goto again;
}
diff --git a/vm_core.h b/vm_core.h
index 9757147f6d..a55942e290 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -1007,7 +1007,6 @@ enum {
VM_FRAME_FLAG_BMETHOD = 0x0040,
VM_FRAME_FLAG_CFRAME = 0x0080,
VM_FRAME_FLAG_LAMBDA = 0x0100,
- VM_FRAME_FLAG_PROC = 0x0200,
/* env flag */
VM_ENV_FLAG_LOCAL = 0x0002,