/*
 * call-seq:
 *      mq.notify = signal   => signal
 *
 * Registers the notification request to deliver a given +signal+
 * 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.
 * If +signal+ is an +IO+ object, it will spawn a thread upon the
 * arrival of the next message and write one "\\0" byte to the file
 * descriptor belonging to that IO object.
 * 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.
 *
 * Notifications are only fired once and processes must reregister
 * for subsequent notifications.
 *
 * 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 = ¬
        VALUE rv = arg;

        notify_cleanup(self);
        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;
        case T_SYMBOL:
        case T_STRING:
                not.sigev_signo = lookup_sig(arg);
                rv = INT2NUM(not.sigev_signo);
                break;
        default:
                rb_raise(rb_eArgError, "must be a signal or nil");
        }

        my_mq_notify(mq->des, notification);

        return rv;
}