--- IO-AIO/AIO.xs 2005/07/31 18:20:07 1.16 +++ IO-AIO/AIO.xs 2005/07/31 18:45:48 1.17 @@ -232,6 +232,77 @@ send_req (req); } +/* work around various missing functions */ + +#if !HAVE_PREADWRITE +# define pread aio_pread +# define pwrite aio_pwrite + +/* + * make our pread/pwrite safe against themselves, but not against + * normal read/write by using a mutex. slows down execution a lot, + * but that's your problem, not mine. + */ +static pthread_mutex_t iolock = PTHREAD_MUTEX_INITIALIZER; + +static ssize_t +pread (int fd, void *buf, size_t count, off_t offset) +{ + ssize_t res; + off_t ooffset; + + pthread_mutex_lock (&iolock); + ooffset = lseek (fd, 0, SEEK_CUR); + lseek (fd, offset, SEEK_SET); + res = read (fd, buf, count); + lseek (fd, ooffset, SEEK_SET); + pthread_mutex_unlock (&iolock); + + return res; +} + +static ssize_t +pwrite (int fd, void *buf, size_t count, off_t offset) +{ + ssize_t res; + off_t ooffset; + + pthread_mutex_lock (&iolock); + ooffset = lseek (fd, 0, SEEK_CUR); + lseek (fd, offset, SEEK_SET); + res = write (fd, buf, count); + lseek (fd, offset, SEEK_SET); + pthread_mutex_unlock (&iolock); + + return res; +} +#endif + +#if !HAVE_FDATASYNC +# define fdatasync fsync +#endif + +#if !HAVE_READAHEAD +# define readahead aio_readahead + +static char readahead_buf[4096]; + +static ssize_t +readahead (int fd, off_t offset, size_t count) +{ + while (count > 0) + { + size_t len = count < sizeof (readahead_buf) ? count : sizeof (readahead_buf); + + pread (fd, readahead_buf, len, offset); + offset += len; + count -= len; + } + + errno = 0; +} +#endif + static void * aio_proc (void *thr_arg) { @@ -266,19 +337,10 @@ switch (type) { -#if HAVE_PREADWRITE case REQ_READ: req->result = pread (req->fd, req->dataptr, req->length, req->offset); break; case REQ_WRITE: req->result = pwrite (req->fd, req->dataptr, req->length, req->offset); break; -#else -# error "pread/pwrite cannot be emulated, fix your os" -#endif -#if HAVE_READAHEAD case REQ_READAHEAD: req->result = readahead (req->fd, req->offset, req->length); break; -#else - // TODO: emulate - case REQ_READAHEAD: req->result = -1; errno = ENOSYS; break; -#endif case REQ_STAT: req->result = stat (req->dataptr, req->statdata); break; case REQ_LSTAT: req->result = lstat (req->dataptr, req->statdata); break; @@ -288,10 +350,7 @@ case REQ_CLOSE: req->result = close (req->fd); break; case REQ_UNLINK: req->result = unlink (req->dataptr); break; - case REQ_FDATASYNC: -#if HAVE_FDATASYNC - req->result = fdatasync (req->fd); break; -#endif + case REQ_FDATASYNC: req->result = fdatasync (req->fd); break; case REQ_FSYNC: req->result = fsync (req->fd); break; case REQ_QUIT: