예제 #1
0
static int
aio_io(struct aiocb *iocb, int (*sysfunc)(struct aiocb *iocb))
{
	struct sigev_node *sn;
	struct sigevent saved_ev;
	int ret, err;

	if (iocb->aio_sigevent.sigev_notify != SIGEV_THREAD) {
		ret = sysfunc(iocb);
		return (ret);
	}

	ret = aio_sigev_alloc(iocb, &sn, &saved_ev);
	if (ret)
		return (ret);
	ret = sysfunc(iocb);
	iocb->aio_sigevent = saved_ev;
	if (ret != 0) {
		err = errno;
		__sigev_list_lock();
		__sigev_delete_node(sn);
		__sigev_list_unlock();
		errno = err;
	}
	return (ret);
}
예제 #2
0
static int
aio_sigev_alloc(struct aiocb *iocb, struct sigev_node **sn,
	struct sigevent *saved_ev)
{
	if (__sigev_check_init()) {
		/* This might be that thread library is not enabled. */
		errno = EINVAL;
		return (-1);
	}

	*sn = __sigev_alloc(SI_ASYNCIO, &iocb->aio_sigevent, NULL, 1);
	if (*sn == NULL) {
		errno = EAGAIN;
		return (-1);
	}
	
	*saved_ev = iocb->aio_sigevent;
	(*sn)->sn_id = (sigev_id_t)iocb;
	__sigev_get_sigevent(*sn, &iocb->aio_sigevent, (*sn)->sn_id);
	(*sn)->sn_dispatch = aio_dispatch;

	__sigev_list_lock();
	__sigev_register(*sn);
	__sigev_list_unlock();

	return (0);
}
예제 #3
0
int
__timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
{
	struct __timer *timer;
	struct sigevent ev;
	struct sigev_node *sn;
	int ret, err;

	timer = malloc(sizeof(struct __timer));
	if (timer == NULL)
		return (-1);

	if (evp == NULL || evp->sigev_notify != SIGEV_THREAD) {
		ret = __sys_ktimer_create(clockid, evp, &timer->oshandle);
		if (ret == -1) {
			err = errno;
			free(timer);
			errno = err;
			return (ret);
		}
		timer->node = NULL;
		*timerid = timer;
		return (0);
	}

	if (__sigev_check_init()) {
		free(timer);
		errno = EINVAL;
		return (-1);
	}

	sn = __sigev_alloc(SI_TIMER, evp, NULL, 0);
	if (sn == NULL) {
		free(timer);
		errno = EAGAIN;
		return (-1);
	}

	__sigev_get_sigevent(sn, &ev, sn->sn_gen);
	ret = __sys_ktimer_create(clockid, &ev, &timer->oshandle);
	if (ret != 0) {
		err = errno;
		__sigev_free(sn);
		free(timer);
		errno = err;
		return (-1);
	}
	sn->sn_flags |= SNF_SYNC;
	sn->sn_dispatch = timer_dispatch;
	sn->sn_id = timer->oshandle;
	timer->node = sn;
	__sigev_list_lock();
	__sigev_register(sn);
	__sigev_list_unlock();
	*timerid = timer;
	return (0);
}
예제 #4
0
파일: mq.c 프로젝트: 2trill2spill/freebsd
int
__mq_notify(mqd_t mqd, const struct sigevent *evp)
{
	struct sigevent ev;
	struct sigev_node *sn;
	int ret;

	if (evp == NULL || evp->sigev_notify != SIGEV_THREAD) {
		if (mqd->node != NULL) {
			__sigev_list_lock();
			__sigev_delete_node(mqd->node);
			mqd->node = NULL;
			__sigev_list_unlock();
		}
		return __sys_kmq_notify(mqd->oshandle, evp);
	}

	if (__sigev_check_init()) {
		/*
		 * Thread library is not enabled.
		 */
		errno = EINVAL;
		return (-1);
	}

	sn = __sigev_alloc(SI_MESGQ, evp, mqd->node, 1);
	if (sn == NULL) {
		errno = EAGAIN;
		return (-1);
	}

	sn->sn_id = mqd->oshandle;
	sn->sn_dispatch = mq_dispatch;
	__sigev_get_sigevent(sn, &ev, sn->sn_gen);
	__sigev_list_lock();
	if (mqd->node != NULL)
		__sigev_delete_node(mqd->node);
	mqd->node = sn;
	__sigev_register(sn);
	ret = __sys_kmq_notify(mqd->oshandle, &ev);
	__sigev_list_unlock();
	return (ret);
}
예제 #5
0
파일: mq.c 프로젝트: 2trill2spill/freebsd
int
__mq_close(mqd_t mqd)
{
	int h;

	if (mqd->node != NULL) {
		__sigev_list_lock();
		__sigev_delete_node(mqd->node);
		__sigev_list_unlock();
	}
	h = mqd->oshandle;
	free(mqd);
	return (__sys_close(h));
}
예제 #6
0
int
__aio_return(struct aiocb *iocb)
{

	if (iocb->aio_sigevent.sigev_notify == SIGEV_THREAD) {
		if (__sys_aio_error(iocb) == EINPROGRESS)
			return (EINPROGRESS);
		__sigev_list_lock();
		__sigev_delete(SI_ASYNCIO, (sigev_id_t)iocb);
		__sigev_list_unlock();
	}

	return __sys_aio_return(iocb);
}
예제 #7
0
int
__timer_delete(timer_t timerid)
{
	int ret, err;

	if (timerid->node != NULL) {
		__sigev_list_lock();
		__sigev_delete_node(timerid->node);
		__sigev_list_unlock();
	}
	ret = __sys_ktimer_delete(timerid->oshandle);
	err = errno;
	free(timerid);
	errno = err;
	return (ret);	
}
예제 #8
0
int
__aio_waitcomplete(struct aiocb **iocbp, struct timespec *timeout)
{
	int err;
	int ret = __sys_aio_waitcomplete(iocbp, timeout);

	if (*iocbp) {
		if ((*iocbp)->aio_sigevent.sigev_notify == SIGEV_THREAD) {
			err = errno;
			__sigev_list_lock();
			__sigev_delete(SI_ASYNCIO, (sigev_id_t)(*iocbp));
			__sigev_list_unlock();
			errno = err;
		}
	}

	return (ret);
}
예제 #9
0
int
__aio_fsync(int op, struct aiocb *iocb)
{
	struct sigev_node *sn;
	struct sigevent saved_ev;
	int ret, err;

	if (iocb->aio_sigevent.sigev_notify != SIGEV_THREAD)
		return __sys_aio_fsync(op, iocb);

	ret = aio_sigev_alloc(iocb, &sn, &saved_ev);
	if (ret)
		return (ret);
	ret = __sys_aio_fsync(op, iocb);
	iocb->aio_sigevent = saved_ev;
	if (ret != 0) {
		err = errno;
		__sigev_list_lock();
		__sigev_delete_node(sn);
		__sigev_list_unlock();
		errno = err;
	}
	return (ret);
}