about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-01-03 05:35:50 +0000
committerEric Wong <normalperson@yhbt.net>2010-01-02 21:39:16 -0800
commit350bfc831938d84cc2d478f2cf88583863cb64fb (patch)
tree190eb0bdb8be5441e09830c88d8bb9d3ab72f87b
parent26015d39e9c848a536b4ea44802f858a4e6e74f7 (diff)
downloadruby_posix_mq-350bfc831938d84cc2d478f2cf88583863cb64fb.tar.gz
FreeBSD implements an __mq_oshandle(mqd_t mqd) function
to convert mqd_t to integer file descriptors.
-rw-r--r--README6
-rw-r--r--ext/posix_mq/extconf.rb1
-rw-r--r--ext/posix_mq/posix_mq.c23
3 files changed, 18 insertions, 12 deletions
diff --git a/README b/README
index 64b6832..c7b65cb 100644
--- a/README
+++ b/README
@@ -13,9 +13,9 @@ network-aware message queue implementations.
 
 * Supports message notifications via signals.
 
-* Supports portable non-blocking operation.  Under Linux 2.6.6+ only,
-  POSIX_MQ objects may even be used with event notification mechanisms
-  such as IO.select.
+* Supports portable non-blocking operation.  Under Linux 2.6.6+ and
+  FreeBSD 7.2+, POSIX_MQ objects may even be used with event
+  notification mechanisms such as IO.select.
 
 * Optional timeouts may be applied to send and receive operations.
 
diff --git a/ext/posix_mq/extconf.rb b/ext/posix_mq/extconf.rb
index e890276..b9e8963 100644
--- a/ext/posix_mq/extconf.rb
+++ b/ext/posix_mq/extconf.rb
@@ -3,6 +3,7 @@ require "mkmf"
 have_header("sys/select.h")
 have_header("signal.h")
 have_header("mqueue.h") or abort "mqueue.h header missing"
+have_func("__mq_oshandle")
 have_func("rb_str_set_len")
 have_func("rb_struct_alloc_noinit")
 have_func('rb_thread_blocking_region')
diff --git a/ext/posix_mq/posix_mq.c b/ext/posix_mq/posix_mq.c
index 8ce1ab5..26e7b65 100644
--- a/ext/posix_mq/posix_mq.c
+++ b/ext/posix_mq/posix_mq.c
@@ -16,21 +16,25 @@
 #include <unistd.h>
 
 #if defined(__linux__)
-#  define MQD_IS_FD 1
-#  define MQ_IO_MARK(mq) rb_gc_mark((mq)->io)
-#  define MQ_IO_SET(mq,val) do { (mq)->io = (val); } while (0)
+#  define MQD_TO_FD(mqd) (int)(mqd)
+#elif defined(HAVE___MQ_OSHANDLE) /* FreeBSD */
+#  define MQD_TO_FD(mqd) __mq_oshandle(mqd)
 #else
 #  warning mqd_t is not select()-able on your OS
-#  define MQD_IS_FD 0
 #  define MQ_IO_MARK(mq) ((void)(0))
 #  define MQ_IO_SET(mq,val) ((void)(0))
-#endif /* non-Linux */
+#endif
+
+#ifdef MQD_TO_FD
+#  define MQ_IO_MARK(mq) rb_gc_mark((mq)->io)
+#  define MQ_IO_SET(mq,val) do { (mq)->io = (val); } while (0)
+#endif
 
 struct posix_mq {
         mqd_t des;
         long msgsize;
         VALUE name;
-#if MQD_IS_FD
+#ifdef MQD_TO_FD
         VALUE io;
 #endif
 };
@@ -469,7 +473,7 @@ static VALUE send0(VALUE self, VALUE buffer)
         return self;
 }
 
-#if MQD_IS_FD
+#ifdef MQD_TO_FD
 /*
  * call-seq:
  *        mq.to_io        => IO
@@ -480,9 +484,10 @@ static VALUE send0(VALUE self, VALUE buffer)
 static VALUE to_io(VALUE self)
 {
         struct posix_mq *mq = get(self, 1);
+        int fd = MQD_TO_FD(mq->des);
 
         if (NIL_P(mq->io))
-                mq->io = rb_funcall(rb_cIO, id_new, 1, INT2NUM(mq->des));
+                mq->io = rb_funcall(rb_cIO, id_new, 1, INT2NUM(fd));
 
         return mq->io;
 }
@@ -818,7 +823,7 @@ void Init_posix_mq_ext(void)
         rb_define_method(cPOSIX_MQ, "notify=", setnotify, 1);
         rb_define_method(cPOSIX_MQ, "nonblock=", setnonblock, 1);
         rb_define_method(cPOSIX_MQ, "nonblock?", getnonblock, 0);
-#if MQD_IS_FD
+#ifdef MQD_TO_FD
         rb_define_method(cPOSIX_MQ, "to_io", to_io, 0);
 #endif