ruby-changes:38949
From: ngoto <ko1@a...>
Date: Thu, 25 Jun 2015 21:42:23 +0900 (JST)
Subject: [ruby-changes:38949] ngoto:r51030 (trunk): * test/-ext-/popen_deadlock/test_popen_deadlock.rb: test [Bug #11265]
ngoto 2015-06-25 21:42:07 +0900 (Thu, 25 Jun 2015) New Revision: 51030 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51030 Log: * 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). Added directories: trunk/ext/-test-/popen_deadlock/ trunk/test/-ext-/popen_deadlock/ Added files: trunk/ext/-test-/popen_deadlock/extconf.rb trunk/ext/-test-/popen_deadlock/infinite_loop_dlsym.c trunk/test/-ext-/popen_deadlock/test_popen_deadlock.rb Modified files: trunk/ChangeLog Index: ChangeLog =================================================================== --- ChangeLog (revision 51029) +++ ChangeLog (revision 51030) @@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Jun 25 21:24:28 2015 Naohisa Goto <ngotogenome@g...> + + * 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@g...> * configure.in: not to use vfork on Solaris to avoid deadlock Index: ext/-test-/popen_deadlock/infinite_loop_dlsym.c =================================================================== --- ext/-test-/popen_deadlock/infinite_loop_dlsym.c (revision 0) +++ ext/-test-/popen_deadlock/infinite_loop_dlsym.c (revision 51030) @@ -0,0 +1,50 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/popen_deadlock/infinite_loop_dlsym.c#L1 +#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); +} Index: ext/-test-/popen_deadlock/extconf.rb =================================================================== --- ext/-test-/popen_deadlock/extconf.rb (revision 0) +++ ext/-test-/popen_deadlock/extconf.rb (revision 51030) @@ -0,0 +1,4 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/popen_deadlock/extconf.rb#L1 +case RUBY_PLATFORM +when /solaris/i, /linux/i + create_makefile("-test-/popen_deadlock/infinite_loop_dlsym") +end Index: test/-ext-/popen_deadlock/test_popen_deadlock.rb =================================================================== --- test/-ext-/popen_deadlock/test_popen_deadlock.rb (revision 0) +++ test/-ext-/popen_deadlock/test_popen_deadlock.rb (revision 51030) @@ -0,0 +1,35 @@ https://github.com/ruby/ruby/blob/trunk/test/-ext-/popen_deadlock/test_popen_deadlock.rb#L1 +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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/