1
0
Fork 0
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:
ngoto 2015-06-25 12:42:07 +00:00
parent d47a2b5712
commit 33a17d4839
4 changed files with 100 additions and 0 deletions

View file

@ -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

View file

@ -0,0 +1,4 @@
case RUBY_PLATFORM
when /solaris/i, /linux/i
create_makefile("-test-/popen_deadlock/infinite_loop_dlsym")
end

View 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);
}

View 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