about summary refs log tree commit homepage
path: root/ext/mahoro/nogvl_compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mahoro/nogvl_compat.h')
-rw-r--r--ext/mahoro/nogvl_compat.h54
1 files changed, 54 insertions, 0 deletions
diff --git a/ext/mahoro/nogvl_compat.h b/ext/mahoro/nogvl_compat.h
new file mode 100644
index 0000000..c5b6778
--- /dev/null
+++ b/ext/mahoro/nogvl_compat.h
@@ -0,0 +1,54 @@
+#ifndef NOGVL_COMPAT_H
+#define NOGVL_COMPAT_H
+/*
+ * Compatibility layer for various GVL-releasing wrappers.
+ *
+ * This layer will be updated to favor compatibility with the latest
+ * Matz Ruby C API, currently Ruby 2.0.0 (as of 2013-04-05).
+ *
+ * rb_thread_call_without_gvl was detectable via have_func in 1.9.3,
+ * but not usable.  So we must check for ruby/thread.h and use
+ * rb_thread_blocking_region if ruby/thread.h is not available
+ *
+ * HAVE_RUBY_THREAD_H is defined by ruby.h in 2.0.0, NOT using
+ * extconf.rb since that may find ruby/thread.h in a different
+ * installation
+ */
+#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && \
+        defined(HAVE_RUBY_THREAD_H) && HAVE_RUBY_THREAD_H /* Ruby 2.0.0 */
+#  include <ruby/thread.h>
+#  define NOGVL(fn,data1,ubf,data2) \
+      rb_thread_call_without_gvl((fn),(data1),(ubf),(data2))
+#elif defined(HAVE_RB_THREAD_BLOCKING_REGION) /* Ruby 1.9.x */
+#  define COMPAT_FN (VALUE (*)(void *))
+#  define NOGVL(fn,data1,ubf,data2) \
+      (void *)rb_thread_blocking_region(COMPAT_FN(fn),(data1),(ubf),(data2))
+#else /* Ruby 1.8 */
+/*
+ * Ruby 1.8 does not have a GVL, we'll just enable signal interrupts
+ * here in case we make interruptible syscalls
+ */
+#  define RUBY_UBF_IO ((rb_unblock_function_t *)-1)
+#  include "rubysig.h"
+typedef void rb_unblock_function_t(void *);
+typedef void *rb_blocking_function_t(void *);
+
+static void *
+fake_nogvl(fn, data1, ubf, data2)
+        rb_blocking_function_t fn;
+        void *data1;
+        rb_unblock_function_t ubf;
+        void *data2;
+{
+        void *rv;
+
+        TRAP_BEG;
+        rv = fn(data1);
+        TRAP_END;
+
+        return rv;
+}
+#  define NOGVL(fn,data1,ubf,data2) fake_nogvl((fn),(data1),(ubf),(data2))
+#endif
+
+#endif /* NOGVL_COMPAT_H */