예제 #1
0
/*
 * 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;
}
예제 #2
0
파일: lily_symtab.c 프로젝트: mvader/lily
lily_sig *lily_build_ensure_sig(lily_symtab *symtab, lily_class *cls,
        int entries_to_use, lily_sig **siglist, int offset)
{
    lily_sig fake_sig;

    fake_sig.cls = cls;
    fake_sig.template_pos = 0;
    fake_sig.siglist = siglist + offset;
    fake_sig.siglist_size = entries_to_use;
    fake_sig.flags = 0;
    fake_sig.next = NULL;

    /* The reason it's done like this is purely to save memory. There's no
       point in creating a new signature if it already exists (since that just
       means the new one has to be destroyed). */
    lily_sig *result_sig = lookup_sig(symtab, &fake_sig);
    if (result_sig == NULL) {
        lily_sig *new_sig = lily_malloc(sizeof(lily_sig));
        lily_sig **new_siglist = lily_malloc(entries_to_use *
                sizeof(lily_sig *));

        if (new_sig == NULL || new_siglist == NULL) {
            lily_free(new_sig);
            lily_free(new_siglist);
            lily_raise_nomem(symtab->raiser);
        }

        memcpy(new_sig, &fake_sig, sizeof(lily_sig));
        memcpy(new_siglist, siglist + offset, sizeof(lily_sig *) * entries_to_use);
        new_sig->siglist = new_siglist;

        new_sig->next = symtab->root_sig;
        symtab->root_sig = new_sig;

        finalize_sig(new_sig);
        result_sig = new_sig;
    }

    return result_sig;
}