mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	
							parent
							
								
									89fbec224d
								
							
						
					
					
						commit
						354cd6f210
					
				
					 2 changed files with 49 additions and 22 deletions
				
			
		| 
						 | 
				
			
			@ -95,31 +95,38 @@ module Timeout
 | 
			
		|||
  end
 | 
			
		||||
  private_constant :Request
 | 
			
		||||
 | 
			
		||||
  def self.ensure_timeout_thread_created
 | 
			
		||||
    unless @timeout_thread
 | 
			
		||||
      TIMEOUT_THREAD_MUTEX.synchronize do
 | 
			
		||||
        @timeout_thread ||= Thread.new do
 | 
			
		||||
          requests = []
 | 
			
		||||
          while true
 | 
			
		||||
            until QUEUE.empty? and !requests.empty? # wait to have at least one request
 | 
			
		||||
              req = QUEUE.pop
 | 
			
		||||
              requests << req unless req.done?
 | 
			
		||||
            end
 | 
			
		||||
            closest_deadline = requests.min_by(&:deadline).deadline
 | 
			
		||||
  def self.create_timeout_thread
 | 
			
		||||
    Thread.new do
 | 
			
		||||
      requests = []
 | 
			
		||||
      while true
 | 
			
		||||
        until QUEUE.empty? and !requests.empty? # wait to have at least one request
 | 
			
		||||
          req = QUEUE.pop
 | 
			
		||||
          requests << req unless req.done?
 | 
			
		||||
        end
 | 
			
		||||
        closest_deadline = requests.min_by(&:deadline).deadline
 | 
			
		||||
 | 
			
		||||
            now = 0.0
 | 
			
		||||
            QUEUE_MUTEX.synchronize do
 | 
			
		||||
              while (now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) < closest_deadline and QUEUE.empty?
 | 
			
		||||
                CONDVAR.wait(QUEUE_MUTEX, closest_deadline - now)
 | 
			
		||||
              end
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
            requests.each do |req|
 | 
			
		||||
              req.interrupt if req.expired?(now)
 | 
			
		||||
            end
 | 
			
		||||
            requests.reject!(&:done?)
 | 
			
		||||
        now = 0.0
 | 
			
		||||
        QUEUE_MUTEX.synchronize do
 | 
			
		||||
          while (now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) < closest_deadline and QUEUE.empty?
 | 
			
		||||
            CONDVAR.wait(QUEUE_MUTEX, closest_deadline - now)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        requests.each do |req|
 | 
			
		||||
          req.interrupt if req.expired?(now)
 | 
			
		||||
        end
 | 
			
		||||
        requests.reject!(&:done?)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  private_class_method :create_timeout_thread
 | 
			
		||||
 | 
			
		||||
  def self.ensure_timeout_thread_created
 | 
			
		||||
    unless @timeout_thread and @timeout_thread.alive?
 | 
			
		||||
      TIMEOUT_THREAD_MUTEX.synchronize do
 | 
			
		||||
        unless @timeout_thread and @timeout_thread.alive?
 | 
			
		||||
          @timeout_thread = create_timeout_thread
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,4 +139,24 @@ class TestTimeout < Test::Unit::TestCase
 | 
			
		|||
    }
 | 
			
		||||
    assert(ok, bug11344)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_fork
 | 
			
		||||
    omit 'fork not supported' unless Process.respond_to?(:fork)
 | 
			
		||||
    r, w = IO.pipe
 | 
			
		||||
    pid = fork do
 | 
			
		||||
      r.close
 | 
			
		||||
      begin
 | 
			
		||||
        r = Timeout.timeout(0.01) { sleep 5 }
 | 
			
		||||
        w.write r.inspect
 | 
			
		||||
      rescue Timeout::Error
 | 
			
		||||
        w.write 'timeout'
 | 
			
		||||
      ensure
 | 
			
		||||
        w.close
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    w.close
 | 
			
		||||
    Process.wait pid
 | 
			
		||||
    assert_equal 'timeout', r.read
 | 
			
		||||
    r.close
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue