Browse Source

Upgrade libeio

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
61448bfc4e
  1. 2
      deps/libeio/Changes
  2. 103
      deps/libeio/eio.c
  3. 52
      deps/libeio/eio.h

2
deps/libeio/Changes

@ -1,6 +1,7 @@
Revision history for libeio Revision history for libeio
TODO: maybe add mincore support? available on at least darwin, solaris, linux, freebsd TODO: maybe add mincore support? available on at least darwin, solaris, linux, freebsd
TODO: openbsd requites stdint.h for intptr_t - why posix?
1.0 1.0
- readdir: correctly handle malloc failures. - readdir: correctly handle malloc failures.
@ -23,4 +24,5 @@ TODO: maybe add mincore support? available on at least darwin, solaris, linux, f
error codes. error codes.
- add OS-independent EIO_MT_* and EIO_MS_* flag enums. - add OS-independent EIO_MT_* and EIO_MS_* flag enums.
- add eio_statvfs/eio_fstatvfs. - add eio_statvfs/eio_fstatvfs.
- add eio_mlock/eio_mlockall and OS-independent MCL_* flag enums.

103
deps/libeio/eio.c

@ -55,7 +55,6 @@
#include <limits.h> #include <limits.h>
#include <fcntl.h> #include <fcntl.h>
#include <assert.h> #include <assert.h>
#include <stdint.h>
#ifndef EIO_FINISH #ifndef EIO_FINISH
# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0 # define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0
@ -77,12 +76,15 @@
# include "config.h" # include "config.h"
# include <sys/time.h> # include <sys/time.h>
# include <sys/select.h> # include <sys/select.h>
# include <sys/mman.h>
# include <unistd.h> # include <unistd.h>
# include <utime.h> # include <utime.h>
# include <signal.h> # include <signal.h>
# include <dirent.h> # include <dirent.h>
#if _POSIX_MEMLOCK || _POSIX_MAPPED_FILES
# include <sys/mman.h>
#endif
/* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */ /* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */
# if __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ # if __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
# define _DIRENT_HAVE_D_TYPE /* sigh */ # define _DIRENT_HAVE_D_TYPE /* sigh */
@ -1395,6 +1397,69 @@ eio__scandir (eio_req *req, etp_worker *self)
} }
} }
#ifdef PAGESIZE
# define eio_pagesize() PAGESIZE
#else
static intptr_t
eio_pagesize (void)
{
static intptr_t page;
if (!page)
page = sysconf (_SC_PAGESIZE);
return page;
}
#endif
static void
eio_page_align (void **addr, size_t *length)
{
intptr_t mask = eio_pagesize () - 1;
/* round down addr */
intptr_t adj = mask & (intptr_t)*addr;
*addr = (void *)((intptr_t)*addr - adj);
*length += adj;
/* round up length */
*length = (*length + mask) & ~mask;
}
#if !_POSIX_MEMLOCK
# define eio__mlock(a,b) ((errno = ENOSYS), -1)
# define eio__mlockall(a) ((errno = ENOSYS), -1)
#else
static int
eio__mlock (void *addr, size_t length)
{
eio_page_align (&addr, &length);
return mlock (addr, length);
}
static int
eio__mlockall (int flags)
{
#if __GLIBC__ == 2 && __GLIBC_MINOR__ <= 7
extern int mallopt (int, int);
mallopt (-6, 238); /* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=473812 */
#endif
if (EIO_MCL_CURRENT != MCL_CURRENT
|| EIO_MCL_FUTURE != MCL_FUTURE)
{
flags = 0
| (flags & EIO_MCL_CURRENT ? MCL_CURRENT : 0)
| (flags & EIO_MCL_FUTURE ? MCL_FUTURE : 0);
}
return mlockall (flags);
}
#endif
#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO) #if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO)
# define eio__msync(a,b,c) ((errno = ENOSYS), -1) # define eio__msync(a,b,c) ((errno = ENOSYS), -1)
#else #else
@ -1402,6 +1467,8 @@ eio__scandir (eio_req *req, etp_worker *self)
int int
eio__msync (void *mem, size_t len, int flags) eio__msync (void *mem, size_t len, int flags)
{ {
eio_page_align (&mem, &len);
if (EIO_MS_ASYNC != MS_SYNC if (EIO_MS_ASYNC != MS_SYNC
|| EIO_MS_INVALIDATE != MS_INVALIDATE || EIO_MS_INVALIDATE != MS_INVALIDATE
|| EIO_MS_SYNC != MS_SYNC) || EIO_MS_SYNC != MS_SYNC)
@ -1420,25 +1487,19 @@ eio__msync (void *mem, size_t len, int flags)
int int
eio__mtouch (void *mem, size_t len, int flags) eio__mtouch (void *mem, size_t len, int flags)
{ {
eio_page_align (&mem, &len);
{
intptr_t addr = (intptr_t)mem; intptr_t addr = (intptr_t)mem;
intptr_t end = addr + len; intptr_t end = addr + len;
#ifdef PAGESIZE intptr_t page = eio_pagesize ();
const intptr_t page = PAGESIZE;
#else
static intptr_t page;
if (!page)
page = sysconf (_SC_PAGESIZE);
#endif
/* round down to start of page, although this is probably useless */
addr &= ~(page - 1); /* assume page size is always a power of two */
if (addr < end) if (addr < end)
if (flags & EIO_MT_MODIFY) /* modify */ if (flags & EIO_MT_MODIFY) /* modify */
do { *((volatile sig_atomic_t *)addr) |= 0; } while ((addr += page) < len); do { *((volatile sig_atomic_t *)addr) |= 0; } while ((addr += page) < len);
else else
do { *((volatile sig_atomic_t *)addr) ; } while ((addr += page) < len); do { *((volatile sig_atomic_t *)addr) ; } while ((addr += page) < len);
}
return 0; return 0;
} }
@ -1624,19 +1685,21 @@ static void eio_execute (etp_worker *self, eio_req *req)
case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break; case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break;
case EIO_MTOUCH: req->result = eio__mtouch (req->ptr2, req->size, req->int1); break; case EIO_MTOUCH: req->result = eio__mtouch (req->ptr2, req->size, req->int1); break;
case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break;
case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break;
case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break; case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break;
case EIO_READDIR: eio__scandir (req, self); break; case EIO_READDIR: eio__scandir (req, self); break;
case EIO_BUSY: case EIO_BUSY:
#ifdef _WIN32 #ifdef _WIN32
Sleep (req->nv1 * 1000.); Sleep (req->nv1 * 1e3);
#else #else
{ {
struct timeval tv; struct timeval tv;
tv.tv_sec = req->nv1; tv.tv_sec = req->nv1;
tv.tv_usec = (req->nv1 - tv.tv_sec) * 1000000.; tv.tv_usec = (req->nv1 - tv.tv_sec) * 1e6;
req->result = select (0, 0, 0, 0, &tv); req->result = select (0, 0, 0, 0, &tv);
} }
@ -1719,6 +1782,16 @@ eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, v
REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND; REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
} }
eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data)
{
REQ (EIO_MLOCK); req->ptr2 = addr; req->size = length; SEND;
}
eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data)
{
REQ (EIO_MLOCKALL); req->int1 = flags; SEND;
}
eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data) eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
{ {
REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND; REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND;

52
deps/libeio/eio.h

@ -67,7 +67,8 @@ typedef int (*eio_cb)(eio_req *req);
/* for readdir */ /* for readdir */
/* eio_readdir flags */ /* eio_readdir flags */
enum { enum
{
EIO_READDIR_DENTS = 0x01, /* ptr2 contains eio_dirents, not just the (unsorted) names */ EIO_READDIR_DENTS = 0x01, /* ptr2 contains eio_dirents, not just the (unsorted) names */
EIO_READDIR_DIRS_FIRST = 0x02, /* dirents gets sorted into a good stat() ing order to find directories first */ EIO_READDIR_DIRS_FIRST = 0x02, /* dirents gets sorted into a good stat() ing order to find directories first */
EIO_READDIR_STAT_ORDER = 0x04, /* dirents gets sorted into a good stat() ing order to quickly stat all files */ EIO_READDIR_STAT_ORDER = 0x04, /* dirents gets sorted into a good stat() ing order to quickly stat all files */
@ -78,7 +79,8 @@ enum {
}; };
/* using "typical" values in the hope that the compiler will do something sensible */ /* using "typical" values in the hope that the compiler will do something sensible */
enum eio_dtype { enum eio_dtype
{
EIO_DT_UNKNOWN = 0, EIO_DT_UNKNOWN = 0,
EIO_DT_FIFO = 1, EIO_DT_FIFO = 1,
EIO_DT_CHR = 2, EIO_DT_CHR = 2,
@ -98,7 +100,8 @@ enum eio_dtype {
EIO_DT_MAX = 15 /* highest DT_VALUE ever, hopefully */ EIO_DT_MAX = 15 /* highest DT_VALUE ever, hopefully */
}; };
struct eio_dirent { struct eio_dirent
{
int nameofs; /* offset of null-terminated name string in (char *)req->ptr2 */ int nameofs; /* offset of null-terminated name string in (char *)req->ptr2 */
unsigned short namelen; /* size of filename without trailing 0 */ unsigned short namelen; /* size of filename without trailing 0 */
unsigned char type; /* one of EIO_DT_* */ unsigned char type; /* one of EIO_DT_* */
@ -107,7 +110,8 @@ struct eio_dirent {
}; };
/* eio_msync flags */ /* eio_msync flags */
enum { enum
{
EIO_MS_ASYNC = 1, EIO_MS_ASYNC = 1,
EIO_MS_INVALIDATE = 2, EIO_MS_INVALIDATE = 2,
EIO_MS_SYNC = 4 EIO_MS_SYNC = 4
@ -115,13 +119,15 @@ enum {
/* eio_mtouch flags */ /* eio_mtouch flags */
enum { enum
{
EIO_MT_MODIFY = 1 EIO_MT_MODIFY = 1
}; };
/* eio_sync_file_range flags */ /* eio_sync_file_range flags */
enum { enum
{
EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1, EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1,
EIO_SYNC_FILE_RANGE_WRITE = 2, EIO_SYNC_FILE_RANGE_WRITE = 2,
EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4 EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4
@ -131,7 +137,8 @@ typedef double eio_tstamp; /* feel free to use double in your code directly */
/* the eio request structure */ /* the eio request structure */
enum { enum
{
EIO_CUSTOM, EIO_CUSTOM,
EIO_OPEN, EIO_CLOSE, EIO_DUP2, EIO_OPEN, EIO_CLOSE, EIO_DUP2,
EIO_READ, EIO_WRITE, EIO_READ, EIO_WRITE,
@ -144,6 +151,7 @@ enum {
EIO_CHOWN, EIO_FCHOWN, EIO_CHOWN, EIO_FCHOWN,
EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC, EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC,
EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE, EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE,
EIO_MLOCK, EIO_MLOCKALL,
EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME, EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME,
EIO_MKNOD, EIO_READDIR, EIO_MKNOD, EIO_READDIR,
EIO_LINK, EIO_SYMLINK, EIO_READLINK, EIO_LINK, EIO_SYMLINK, EIO_READLINK,
@ -151,6 +159,21 @@ enum {
EIO_BUSY EIO_BUSY
}; };
/* mlockall constants */
enum
{
EIO_MCL_CURRENT = 1,
EIO_MCL_FUTURE = 2,
};
/* request priorities */
enum {
EIO_PRI_MIN = -4,
EIO_PRI_MAX = 4,
EIO_PRI_DEFAULT = 0
};
/* eio request structure */ /* eio request structure */
/* this structure is mostly read-only */ /* this structure is mostly read-only */
/* when initialising it, all members must be zero-initialised */ /* when initialising it, all members must be zero-initialised */
@ -160,14 +183,14 @@ struct eio_req
ssize_t result; /* result of syscall, e.g. result = read (... */ ssize_t result; /* result of syscall, e.g. result = read (... */
off_t offs; /* read, write, truncate, readahead, sync_file_range: file offset */ off_t offs; /* read, write, truncate, readahead, sync_file_range: file offset */
size_t size; /* read, write, readahead, sendfile, msync, sync_file_range: length */ size_t size; /* read, write, readahead, sendfile, msync, mlock, sync_file_range: length */
void *ptr1; /* all applicable requests: pathname, old name; readdir: optional eio_dirents */ void *ptr1; /* all applicable requests: pathname, old name; readdir: optional eio_dirents */
void *ptr2; /* all applicable requests: new name or memory buffer; readdir: name strings */ void *ptr2; /* all applicable requests: new name or memory buffer; readdir: name strings */
eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */ eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */
eio_tstamp nv2; /* utime, futime: mtime */ eio_tstamp nv2; /* utime, futime: mtime */
int type; /* EIO_xxx constant ETP */ int type; /* EIO_xxx constant ETP */
int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, readdir: flags */ int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range: flags */ long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range: flags */
long int3; /* chown, fchown: gid; mknod: dev_t */ long int3; /* chown, fchown: gid; mknod: dev_t */
int errorno; /* errno value on syscall return */ int errorno; /* errno value on syscall return */
@ -185,7 +208,7 @@ struct eio_req
eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */ eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */
}; };
/* _private_ flags */ /* _private_ request flags */
enum { enum {
EIO_FLAG_CANCELLED = 0x01, /* request was cancelled */ EIO_FLAG_CANCELLED = 0x01, /* request was cancelled */
EIO_FLAG_PTR1_FREE = 0x02, /* need to free(ptr1) */ EIO_FLAG_PTR1_FREE = 0x02, /* need to free(ptr1) */
@ -193,11 +216,8 @@ enum {
EIO_FLAG_GROUPADD = 0x08 /* some request was added to the group */ EIO_FLAG_GROUPADD = 0x08 /* some request was added to the group */
}; };
enum { /* undocumented/unsupported/private helper */
EIO_PRI_MIN = -4, /*void eio_page_align (void **addr, size_t *length);*/
EIO_PRI_MAX = 4,
EIO_PRI_DEFAULT = 0,
};
/* returns < 0 on error, errno set /* returns < 0 on error, errno set
* need_poll, if non-zero, will be called when results are available * need_poll, if non-zero, will be called when results are available
@ -238,6 +258,8 @@ eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data); eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data); eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data); eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data);
eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data);
eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data); eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data);
eio_req *eio_close (int fd, int pri, eio_cb cb, void *data); eio_req *eio_close (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data); eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data);

Loading…
Cancel
Save