--- aiops.c.orig Mon Aug 20 09:55:31 2001 +++ aiops.c Mon Sep 17 21:05:09 2001 @@ -47,6 +47,14 @@ #include #endif +#define WITH_AIO_AND_KEVENT +#ifdef WITH_AIO_AND_KEVENT +#include +#include +#include +#include +#endif + #define RIDICULOUS_LENGTH 4096 enum _squidaio_thread_status { @@ -125,7 +133,7 @@ static void squidaio_cleanup_request(squidaio_request_t *); static void *squidaio_thread_loop(void *); static void squidaio_do_open(squidaio_request_t *); -static void squidaio_do_read(squidaio_request_t *); +static void squidaio_do_read(squidaio_request_t *, int); static void squidaio_do_write(squidaio_request_t *); static void squidaio_do_close(squidaio_request_t *); static void squidaio_do_stat(squidaio_request_t *); @@ -326,6 +334,15 @@ squidaio_thread_t *threadp = ptr; squidaio_request_t *request; sigset_t new; +#ifdef WITH_AIO_AND_KEVENT + int kq; +#endif + +#ifdef WITH_AIO_AND_KEVENT + kq = kqueue(); + if( kq == -1 ) + return NULL; +#endif /* * Make sure to ignore signals which may possibly get sent to @@ -375,7 +392,11 @@ squidaio_do_open(request); break; case _AIO_OP_READ: - squidaio_do_read(request); +#ifdef WITH_AIO_AND_KEVENT + squidaio_do_read(request, kq); +#else + squidaio_do_read(request, -1); +#endif break; case _AIO_OP_WRITE: squidaio_do_write(request); @@ -414,6 +435,9 @@ pthread_mutex_unlock(&done_queue.mutex); threadp->requests++; } /* while forever */ +#ifdef WITH_AIO_AND_KEVENT + close( kq ); +#endif return NULL; } /* squidaio_thread_loop */ @@ -621,8 +645,66 @@ static void -squidaio_do_read(squidaio_request_t * requestp) +squidaio_do_read(squidaio_request_t * requestp, int kq ) { +#ifdef WITH_AIO_AND_KEVENT + struct aiocb cb; + int rc; + if( kq == -1 ) + goto OldMode; + memset( &cb, 0, sizeof cb ); + /* Convert offset to absolute. */ + if( requestp->whence != SEEK_SET ) { + cb.aio_offset = lseek( + requestp->fd, requestp->offset, requestp->whence ); + if( cb.aio_offset == -1 ) { + requestp->ret = -1; + requestp->err = errno; + return; + } + } + else + cb.aio_offset = requestp->offset; + /* Fill request. */ + cb.aio_fildes = requestp->fd; + cb.aio_buf = requestp->tmpbufp; + cb.aio_nbytes = requestp->buflen; + cb.aio_sigevent.sigev_notify = SIGEV_KEVENT; + cb.aio_sigevent.sigev_value.sigval_ptr = &cb; + cb.aio_sigevent.sigev_notify_kqueue = kq; + /* Queue request. + * Fall back to blocking mode on any error. Reason does not matter. + */ + if( aio_read( &cb ) < 0 ) + goto OldMode; + /* Wait for termination. Termination will be caught as kevent. */ + for(;;) { + struct kevent kev; + struct pollfd pf; + struct timespec ts; + /* Wait for kevent */ + memset( &pf, 0, sizeof pf ); + pf.fd = kq; + pf.events = POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI; + rc = poll( &pf, 1, 20 ); + if( rc < 1 ) + continue; + /* Peek event from queue. Its contents do not matter. */ + ts.tv_sec = 0; + ts.tv_nsec = 0; + rc = kevent( kq, NULL, 0, &kev, 1, &ts ); + /* Check for termination. */ + rc = aio_error( &cb ); + if( rc != EINPROGRESS ) + break; + } + /* Get operation return value and record it. */ + requestp->err = rc; + requestp->ret = aio_return( &cb ); + return; + +OldMode: +#endif lseek(requestp->fd, requestp->offset, requestp->whence); requestp->ret = read(requestp->fd, requestp->tmpbufp, requestp->buflen); requestp->err = errno;