Issue #14859 has been updated by Eregon (Benoit Daloze).


normalperson (Eric Wong) wrote:
> eregontp / gmail.com wrote:
>  > Something else, I would consider Timeout to be fundamentally
>  > flawed as long as it relies on Thread#raise, because it can
>  > fire in the middle of an ensure block:
>  > http://headius.blogspot.com/2008/02/rubys-threadraise-threadkill-timeoutrb.html
>  
>  We have Thread.handle_interrupt, nowadays, to control when
>  interrupts fire.

Right, although it's very difficult to use correctly (for instance, it's incorrect to use Thread.handle_interrupt inside the ensure block) and can easily cause hangs or deadlocks.

BTW, it looks like MonitorMixin::ConditionVariable doesn't use Thread.handle_interrupt and could continue out of #wait (with an exception thrown by Thread#raise) without reacquiring the lock.


It might be nice to have a Timeout variant that only interrupts blocking IO, without relying on Thread#raise (but just SIGVTALRM).
I think that would be easier/safer to use than the current Timeout.timeout().
Not sure how to deal if there are multiple IO calls inside that Timeout block though.
And there could still be blocking IO in an ensure block, which would not work as intended.

> I considered that, too, but we'd need to add timeouts to every
single method which can block. There are many: File.open, Queue#pop,
SizedQueue#push, Mutex#lock/synchronize, Process.wait*,
IO#gets, IO#write, IO#read, IO#getc, IO.copy_stream, ...

It seems fine to me. Other implementations already have a timeout on Queue#pop IIRC.
I'm not sure we need all of them right now (what use case for Mutex#lock/synchronize ?).
I think the main need would be for standard IO like IO#read/write, especially on sockets and pipes.

----------------------------------------
Feature #14859: [PATCH] implement Timeout in VM
https://bugs.ruby-lang.org/issues/14859#change-72611

* Author: normalperson (Eric Wong)
* Status: Open
* Priority: Normal
* Assignee: ko1 (Koichi Sasada)
* Target version: 
----------------------------------------
implement Timeout in VM

Based on the ugliness of handling partial writes with
IO#write_nonblock and inability to use writev(2) effectively
with write timeouts in Net::HTTP in r63587-r63589, I've
decided Timeout to be the more programmer-friendly option
to use and to improve it.

Timeout is significantly faster with this patch, and stopping
the timeout before expiration (common case) is optimized to be
as fast as possible.  This version relies on timer-thread to
provide wakeup interrupts.

This is a minimally intrusive patch.  I also started working on
a more intrusive patch to touch all sleep/waiting function
calls, but this is easier-to-review for now.  In the future,
I will try per-thread timeouts and eliminate timer-thread
for platforms with POSIX timers (timer_create/timer_settime)

Speedup ratio: compare with the result of `trunk' (greater is better)

timeout_mt_nested       3.887
timeout_mt_same         3.843
timeout_mt_ugly         1.335
timeout_nested          7.059
timeout_same            5.173
timeout_zero            2.587


---Files--------------------------------
0001-implement-Timeout-in-VM.patch (27.2 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>