summaryrefslogtreecommitdiff
path: root/ext/-test-/popen_deadlock
diff options
context:
space:
mode:
authorngoto <ngoto@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-06-25 12:42:07 +0000
committerngoto <ngoto@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-06-25 12:42:07 +0000
commit33a17d48397518c2110be41ad8793705a701a7fe (patch)
tree89b3058f989dc8e79b490b03d614efcac13a92fa /ext/-test-/popen_deadlock
parentd47a2b571296b9e726531f61690010eb1fa3d402 (diff)
* 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
Diffstat (limited to 'ext/-test-/popen_deadlock')
-rw-r--r--ext/-test-/popen_deadlock/extconf.rb4
-rw-r--r--ext/-test-/popen_deadlock/infinite_loop_dlsym.c50
2 files changed, 54 insertions, 0 deletions
diff --git a/ext/-test-/popen_deadlock/extconf.rb b/ext/-test-/popen_deadlock/extconf.rb
new file mode 100644
index 0000000..f993ff7
--- /dev/null
+++ b/ext/-test-/popen_deadlock/extconf.rb
@@ -0,0 +1,4 @@
+case RUBY_PLATFORM
+when /solaris/i, /linux/i
+ create_makefile("-test-/popen_deadlock/infinite_loop_dlsym")
+end
diff --git a/ext/-test-/popen_deadlock/infinite_loop_dlsym.c b/ext/-test-/popen_deadlock/infinite_loop_dlsym.c
new file mode 100644
index 0000000..1d95a7c
--- /dev/null
+++ b/ext/-test-/popen_deadlock/infinite_loop_dlsym.c
@@ -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);
+}