From 84c338613e4dbad9f61cb6d8ea10c8cdc09faa98 Mon Sep 17 00:00:00 2001 From: Venkatesh Srinivas Date: Fri, 25 Feb 2011 19:40:31 -0800 Subject: [PATCH] librt -- AIO: Implement SIGEV_THREAD for AIO completion notification. SIGEV_THREAD launches a libthread thread in response to I/O completion. We link librt against libthread to allow access to the pthread_* routines. --- lib/librt/Makefile | 1 + lib/librt/aio.c | 80 ++++++++++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/lib/librt/Makefile b/lib/librt/Makefile index defdab9cd1..5f0fec97c2 100644 --- a/lib/librt/Makefile +++ b/lib/librt/Makefile @@ -1,6 +1,7 @@ LIB=rt SHLIB_MAJOR=0 WARNS?=2 +LDADD+=-pthread SRCS+= mq.c aio.c diff --git a/lib/librt/aio.c b/lib/librt/aio.c index 487aa6681a..7c87c1e98d 100644 --- a/lib/librt/aio.c +++ b/lib/librt/aio.c @@ -21,10 +21,7 @@ * routines. * * This version cannot perform asynchronous notification of I/O completion - * on DragonFly via SIGEV_THREAD or SIGEV_SIGNAL. - * - * 1) SIGEV_THREAD is not supported by DFly's sigevent structure or any - * other machinery in libthread or librt. + * on DragonFly via SIGEV_SIGNAL. * * 2) SIGEV_SIGNAL code is present, but if-ed out under 'notyet'; Dfly * does not support sigqueue(), so we cannot control the payload to @@ -43,39 +40,51 @@ #include #include #include +#include + +static void *_aio_thr_start(void *); static void -_aio_signal(struct aiocb *ap) +_aio_notify(struct sigevent *sigevp) { -#ifdef notyet int sig; union sigval sv; pid_t pid; + pthread_t thr; - if (ap->aio_sigevent.sigev_notify == SIGEV_NONE) + switch (sigevp->sigev_notify) { + case SIGEV_NONE: return; - sig = ap->aio_sigevent.sigev_signo; - sv = ap->aio_sigevent.sigev_value; - - sigqueue(pid, sig, sv); -#endif -} + case SIGEV_THREAD: + pthread_create(&thr, + sigevp->sigev_notify_attributes, + _aio_thr_start, + sigevp); + break; -static void -_lio_signal(struct sigevent *sigevp) -{ + case SIGEV_SIGNAL: #ifdef notyet - int sig; - union sigval sv; - pid_t pid; - - pid = getpid(); - sig = sigevp->sigev_signo; - sv = sigevp->sigev_value; + pid = getpid(); + sig = sigevp->sigev_signo; + sv = sigevp->sigev_value; + sigqueue(pid, sig, sv); +#endif + break; - sigqueue(pid, sig, sv); + case SIGEV_KEVENT: +#ifdef notyet #endif + break; + } +} + +static void * +_aio_thr_start(void *vsigevp) +{ + struct sigevent *sigevp = vsigevp; + sigevp->sigev_notify_function(sigevp->sigev_value); + return (NULL); } /* @@ -87,7 +96,8 @@ int aio_read(struct aiocb *ap) { #ifndef notyet - if (ap->aio_sigevent.sigev_notify != SIGEV_NONE) + if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) && + (ap->aio_sigevent.sigev_notify != SIGEV_THREAD)) return (ENOSYS); #endif @@ -97,7 +107,7 @@ aio_read(struct aiocb *ap) ap->aio_offset); ap->_aio_err = errno; - _aio_signal(ap); + _aio_notify(&ap->aio_sigevent); return (0); } @@ -106,7 +116,8 @@ int aio_write(struct aiocb *ap) { #ifndef notyet - if (ap->aio_sigevent.sigev_notify != SIGEV_NONE) + if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) && + (ap->aio_sigevent.sigev_notify != SIGEV_THREAD)) return (ENOSYS); #endif @@ -116,7 +127,7 @@ aio_write(struct aiocb *ap) ap->aio_offset); ap->_aio_err = errno; - _aio_signal(ap); + _aio_notify(&ap->aio_sigevent); return (0); } @@ -125,14 +136,15 @@ int aio_fsync(int op, struct aiocb *ap) { #ifndef notyet - if (ap->aio_sigevent.sigev_notify != SIGEV_NONE) + if ((ap->aio_sigevent.sigev_notify != SIGEV_NONE) && + (ap->aio_sigevent.sigev_notify != SIGEV_THREAD)) return (ENOSYS); #endif ap->_aio_val = fsync(ap->aio_fildes); ap->_aio_err = errno; - _aio_signal(ap); + _aio_notify(&ap->aio_sigevent); return(0); } @@ -144,7 +156,8 @@ lio_listio(int mode, struct aiocb *const apv[], int nent, int i; #ifndef notyet - if (sigevp && sigevp->sigev_notify != SIGEV_NONE) + if ((sigevp->sigev_notify != SIGEV_NONE) && + (sigevp->sigev_notify != SIGEV_THREAD)) return (ENOSYS); #endif @@ -161,10 +174,9 @@ lio_listio(int mode, struct aiocb *const apv[], int nent, } if (sigevp && - (mode == LIO_NOWAIT) && - (sigevp->sigev_notify == SIGEV_SIGNAL) + (mode == LIO_NOWAIT) ) { - _lio_signal(sigevp); + _aio_notify(sigevp); } return (0); -- 2.41.0