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
Reference in a new issue