about summary refs log tree commit homepage
path: root/ext/posix_mq/posix_mq.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-01-02 20:41:39 -0800
committerEric Wong <normalperson@yhbt.net>2010-01-02 20:57:54 -0800
commit6f24b5626f89fbb6445c0943ba71f56c8945e18f (patch)
tree62a739ddbb2a792a4864f7e5f7c97368e816d30e /ext/posix_mq/posix_mq.c
parent522d4d1472c216bd95a16ca5b118bc14693aad64 (diff)
downloadruby_posix_mq-6f24b5626f89fbb6445c0943ba71f56c8945e18f.tar.gz
"mq.notify = false" also works now, doing what
"mq.notify = nil" used to do (using SIGEV_NONE).

I was confused by SIGEV_NONE usage vs using a NULL pointer for
the notification passed mq_notify(3).  SIGEV_NONE does not
actually unregister, it registers a no-op notification which
prevents other processes from taking us.

This also fixes the test case to pass under both Linux and
FreeBSD.
Diffstat (limited to 'ext/posix_mq/posix_mq.c')
-rw-r--r--ext/posix_mq/posix_mq.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/ext/posix_mq/posix_mq.c b/ext/posix_mq/posix_mq.c
index e64cac3..014927e 100644
--- a/ext/posix_mq/posix_mq.c
+++ b/ext/posix_mq/posix_mq.c
@@ -680,19 +680,32 @@ static int lookup_sig(VALUE sig)
  * to the current process when message is received.
  * If +signal+ is +nil+, it will unregister and disable the notification
  * request to allow other processes to register a request.
+ * If +signal+ is +false+, it will register a no-op notification request
+ * which will prevent other processes from registering a notification.
  * Only one process may have a notification request for a queue
  * at a time, Errno::EBUSY will be raised if there is already
  * a notification request registration for the queue.
+ *
+ * For readers of the mq_notify(3) manpage, passing +false+
+ * is equivalent to SIGEV_NONE, and passing +nil+ is equivalent
+ * of passing a NULL notification pointer to mq_notify(3).
  */
 static VALUE setnotify(VALUE self, VALUE arg)
 {
         struct posix_mq *mq = get(self, 1);
         struct sigevent not;
+        struct sigevent * notification = &not;
         VALUE rv = arg;
 
         not.sigev_notify = SIGEV_SIGNAL;
 
         switch (TYPE(arg)) {
+        case T_FALSE:
+                not.sigev_notify = SIGEV_NONE;
+                break;
+        case T_NIL:
+                notification = NULL;
+                break;
         case T_FIXNUM:
                 not.sigev_signo = NUM2INT(arg);
                 break;
@@ -701,15 +714,12 @@ static VALUE setnotify(VALUE self, VALUE arg)
                 not.sigev_signo = lookup_sig(arg);
                 rv = INT2NUM(not.sigev_signo);
                 break;
-        case T_NIL:
-                not.sigev_notify = SIGEV_NONE;
-                break;
         default:
                 /* maybe support Proc+thread via sigev_notify_function.. */
                 rb_raise(rb_eArgError, "must be a signal or nil");
         }
 
-        if (mq_notify(mq->des, &not) == MQD_INVALID)
+        if (mq_notify(mq->des, notification) == MQD_INVALID)
                 rb_sys_fail("mq_notify");
 
         return rv;