diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-06-06 22:55:35 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-06-06 22:55:35 +0000 |
commit | 10421fb1f24e9f8d46d370c7d31725eaa457b6ed (patch) | |
tree | 5de99ccb6f5bbe8d954ba742d91c75abf7be564b /thread.c | |
parent | 95af3295cc6804e0c44f50f50b1aedf5d0c5ffcf (diff) | |
download | ruby-10421fb1f24e9f8d46d370c7d31725eaa457b6ed.tar.gz |
IO#close: do not enqueue redundant interrupts (take #2)
Enqueuing multiple errors for one event causes spurious errors
down the line, as reported by Nikolay Vashchenko in
https://bugs.ruby-lang.org/issues/13632
This should fix bad interactions with test_race_gets_and_close
in test/ruby/test_io.rb since we ensure rb_notify_fd_close
continues returning the busy flag after enqueuing the interrupt.
Backporting changes to 2.4 and earlier releases will be more
challenging...
* thread.c (rb_notify_fd_close): do not enqueue multiple interrupts
[ruby-core:81581] [Bug #13632]
* test/ruby/test_io.rb (test_single_exception_on_close):
new test based on script from Nikolay
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59028 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 10 |
1 files changed, 8 insertions, 2 deletions
@@ -2212,10 +2212,16 @@ rb_notify_fd_close(int fd) list_for_each(&vm->waiting_fds, wfd, wfd_node) { if (wfd->fd == fd) { rb_thread_t *th = wfd->th; - VALUE err = th->vm->special_exceptions[ruby_error_stream_closed]; + VALUE err; + + busy = 1; + if (!th) { + continue; + } + wfd->th = 0; + err = th->vm->special_exceptions[ruby_error_stream_closed]; rb_threadptr_pending_interrupt_enque(th, err); rb_threadptr_interrupt(th); - busy = 1; } } return busy; |