mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* test/-ext-/popen_deadlock/test_popen_deadlock.rb: test [Bug #11265]
* ext/-test-/popen_deadlock/infinite_loop_dlsym.c: new ext to call dlsym(3) infinitely without GVL, used in the above test. * ext/-test-/popen_deadlock/extconf.rb: extconf.rb for the above ext. Currently, only enabled on Solaris (main target) and Linux (as a reference platform and for debugging the ext). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51030 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									d47a2b5712
								
							
						
					
					
						commit
						33a17d4839
					
				
					 4 changed files with 100 additions and 0 deletions
				
			
		
							
								
								
									
										11
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,14 @@
 | 
			
		|||
Thu Jun 25 21:24:28 2015  Naohisa Goto  <ngotogenome@gmail.com>
 | 
			
		||||
 | 
			
		||||
	* test/-ext-/popen_deadlock/test_popen_deadlock.rb: test [Bug #11265]
 | 
			
		||||
 | 
			
		||||
	* ext/-test-/popen_deadlock/infinite_loop_dlsym.c: new ext to call
 | 
			
		||||
	  dlsym(3) infinitely without GVL, used in the above test.
 | 
			
		||||
 | 
			
		||||
	* ext/-test-/popen_deadlock/extconf.rb: extconf.rb for the above
 | 
			
		||||
	  ext. Currently, only enabled on Solaris (main target) and Linux
 | 
			
		||||
	  (as a reference platform and for debugging the ext).
 | 
			
		||||
 | 
			
		||||
Thu Jun 25 19:24:25 2015  Naohisa Goto  <ngotogenome@gmail.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in: not to use vfork on Solaris to avoid deadlock
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								ext/-test-/popen_deadlock/extconf.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								ext/-test-/popen_deadlock/extconf.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
case RUBY_PLATFORM
 | 
			
		||||
when /solaris/i, /linux/i
 | 
			
		||||
  create_makefile("-test-/popen_deadlock/infinite_loop_dlsym")
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										50
									
								
								ext/-test-/popen_deadlock/infinite_loop_dlsym.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								ext/-test-/popen_deadlock/infinite_loop_dlsym.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
#include "ruby/ruby.h"
 | 
			
		||||
#include "ruby/thread.h"
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
 | 
			
		||||
struct data_for_loop_dlsym {
 | 
			
		||||
    const char *name;
 | 
			
		||||
    volatile int stop;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void*
 | 
			
		||||
native_loop_dlsym(void *data)
 | 
			
		||||
{
 | 
			
		||||
    struct data_for_loop_dlsym *s = data;
 | 
			
		||||
 | 
			
		||||
    while (!(s->stop)) {
 | 
			
		||||
        dlsym(RTLD_DEFAULT, s->name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ubf_for_loop_dlsym(void *data)
 | 
			
		||||
{
 | 
			
		||||
    struct data_for_loop_dlsym *s = data;
 | 
			
		||||
 | 
			
		||||
    s->stop = 1;
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
loop_dlsym(VALUE self, VALUE name)
 | 
			
		||||
{
 | 
			
		||||
    struct data_for_loop_dlsym d;
 | 
			
		||||
 | 
			
		||||
    d.stop = 0;
 | 
			
		||||
    d.name = StringValuePtr(name);
 | 
			
		||||
 | 
			
		||||
    rb_thread_call_without_gvl(native_loop_dlsym, &d,
 | 
			
		||||
                               ubf_for_loop_dlsym, &d);
 | 
			
		||||
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Init_infinite_loop_dlsym(void)
 | 
			
		||||
{
 | 
			
		||||
    rb_define_method(rb_cThread, "__infinite_loop_dlsym__", loop_dlsym, 1);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								test/-ext-/popen_deadlock/test_popen_deadlock.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								test/-ext-/popen_deadlock/test_popen_deadlock.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
begin
 | 
			
		||||
  require '-test-/popen_deadlock/infinite_loop_dlsym'
 | 
			
		||||
rescue LoadError
 | 
			
		||||
  skip = true
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class TestPopenDeadlock < Test::Unit::TestCase
 | 
			
		||||
 | 
			
		||||
  # [Bug #11265]
 | 
			
		||||
  def assert_popen_without_deadlock
 | 
			
		||||
    assert_separately([], <<-"end;", timeout: 90) #do
 | 
			
		||||
        require '-test-/popen_deadlock/infinite_loop_dlsym'
 | 
			
		||||
 | 
			
		||||
        bug = '11265'.freeze
 | 
			
		||||
        begin
 | 
			
		||||
          t = Thread.new {
 | 
			
		||||
            Thread.current.__infinite_loop_dlsym__("_ex_unwind")
 | 
			
		||||
          }
 | 
			
		||||
          str = IO.popen([ 'echo', bug ], 'r+') { |io| io.read }
 | 
			
		||||
          assert_equal(bug, str.chomp)
 | 
			
		||||
        ensure
 | 
			
		||||
          t.kill if t
 | 
			
		||||
        end
 | 
			
		||||
    end;
 | 
			
		||||
  end
 | 
			
		||||
  private :assert_popen_without_deadlock
 | 
			
		||||
 | 
			
		||||
  # 10 test methods are defined for showing progess reports
 | 
			
		||||
  10.times do |i|
 | 
			
		||||
    define_method("test_popen_without_deadlock_#{i}") {
 | 
			
		||||
      assert_popen_without_deadlock
 | 
			
		||||
    }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end unless skip #class TestPopenDeadlock
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue