mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	thread.c: fix deadlock
* thread.c (thread_join_sleep): the target thread may exit during `RUBY_VM_CHECK_INTS_BLOCKING`, but `sleep_forever` does not consider the condition change to wait. [ruby-core:84248] [Bug #14181] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61274 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									57b0489cdb
								
							
						
					
					
						commit
						f5183827dc
					
				
					 2 changed files with 45 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -1249,4 +1249,42 @@ q.pop
 | 
			
		|||
      end
 | 
			
		||||
    _end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_signal_at_join
 | 
			
		||||
    if /mswin|mingw/ =~ RUBY_PLATFORM
 | 
			
		||||
      skip "can't trap a signal from another process on Windows"
 | 
			
		||||
      # opt = {new_pgroup: true}
 | 
			
		||||
    end
 | 
			
		||||
    assert_separately([], "#{<<~"{#"}\n#{<<~'};'}")
 | 
			
		||||
    {#
 | 
			
		||||
      n = 1000
 | 
			
		||||
      sig = :INT
 | 
			
		||||
      trap(sig) {}
 | 
			
		||||
      IO.popen([EnvUtil.rubybin, "-e", "#{<<~"{#1"}\n#{<<~'};#1'}"], "r+") do |f|
 | 
			
		||||
        tpid = #{$$}
 | 
			
		||||
        sig = :#{sig}
 | 
			
		||||
        {#1
 | 
			
		||||
          STDOUT.sync = true
 | 
			
		||||
          while gets
 | 
			
		||||
            puts
 | 
			
		||||
            Process.kill(sig, tpid)
 | 
			
		||||
          end
 | 
			
		||||
        };#1
 | 
			
		||||
        assert_nothing_raised do
 | 
			
		||||
          n.times do
 | 
			
		||||
            w = Thread.start do
 | 
			
		||||
              sleep 30
 | 
			
		||||
            end
 | 
			
		||||
            begin
 | 
			
		||||
              f.puts
 | 
			
		||||
              f.gets
 | 
			
		||||
            ensure
 | 
			
		||||
              w.kill
 | 
			
		||||
              w.join
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    };
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								thread.c
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								thread.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -883,7 +883,13 @@ thread_join_sleep(VALUE arg)
 | 
			
		|||
 | 
			
		||||
    while (target_th->status != THREAD_KILLED) {
 | 
			
		||||
	if (forever) {
 | 
			
		||||
	    sleep_forever(th, TRUE, FALSE);
 | 
			
		||||
	    th->status = THREAD_STOPPED_FOREVER;
 | 
			
		||||
	    th->vm->sleeper++;
 | 
			
		||||
	    rb_check_deadlock(th->vm);
 | 
			
		||||
	    native_sleep(th, 0);
 | 
			
		||||
	    th->vm->sleeper--;
 | 
			
		||||
	    RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
 | 
			
		||||
	    th->status = THREAD_RUNNABLE;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    double now = timeofday();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue