ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libeio/eio.c
(Generate patch)

Comparing libeio/eio.c (file contents):
Revision 1.84 by root, Thu Jul 7 22:39:56 2011 UTC vs.
Revision 1.86 by root, Thu Jul 14 18:30:10 2011 UTC

54#include <stdlib.h> 54#include <stdlib.h>
55#include <string.h> 55#include <string.h>
56#include <errno.h> 56#include <errno.h>
57#include <sys/types.h> 57#include <sys/types.h>
58#include <sys/stat.h> 58#include <sys/stat.h>
59#include <sys/statvfs.h>
60#include <limits.h> 59#include <limits.h>
61#include <fcntl.h> 60#include <fcntl.h>
62#include <assert.h> 61#include <assert.h>
63 62
63#include <sys/statvfs.h>
64/* intptr_t comes from unistd.h, says POSIX/UNIX/tradition */ 64/* intptr_t comes from unistd.h, says POSIX/UNIX/tradition */
65/* intptr_t only comes from stdint.h, says idiot openbsd coder */ 65/* intptr_t only comes from stdint.h, says idiot openbsd coder */
66#if HAVE_STDINT_H 66#if HAVE_STDINT_H
67# include <stdint.h> 67# include <stdint.h>
68#endif 68#endif
83 83
84#ifndef EIO_FEED 84#ifndef EIO_FEED
85# define EIO_FEED(req) do { if ((req)->feed ) (req)->feed (req); } while (0) 85# define EIO_FEED(req) do { if ((req)->feed ) (req)->feed (req); } while (0)
86#endif 86#endif
87 87
88#ifndef EIO_FD_TO_WIN32_HANDLE
89# define EIO_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd)
90#endif
91#ifndef EIO_WIN32_HANDLE_TO_FD
92# define EIO_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0)
93#endif
94
95#define EIO_ERRNO(errval,retval) ((errno = errval), retval)
96
97#define EIO_ENOSYS() EIO_ERRNO (ENOSYS, -1)
98
88#ifdef _WIN32 99#ifdef _WIN32
89 100
90 /*doh*/ 101 #define PAGESIZE 4096 /* GetSystemInfo? */
102
103 #define stat(path,buf) _stati64 (path,buf)
104 #define lstat(path,buf) stat (path,buf)
105 #define fstat(fd,buf) _fstati64 (path,buf)
106 #define fsync(fd) (FlushFileBuffers (EIO_FD_TO_WIN32_HANDLE (fd)) ? 0 : EIO_ERRNO (EBADF, -1))
107 #define mkdir(path,mode) _mkdir (path)
108 #define link(old,neu) (CreateHardLink (neu, old, 0) ? 0 : EIO_ERRNO (ENOENT, -1))
109
110 #define chown(path,uid,gid) EIO_ENOSYS ()
111 #define fchown(fd,uid,gid) EIO_ENOSYS ()
112 #define truncate(path,offs) EIO_ENOSYS () /* far-miss: SetEndOfFile */
113 #define ftruncate(fd,offs) EIO_ENOSYS () /* near-miss: SetEndOfFile */
114 #define mknod(path,mode,dev) EIO_ENOSYS ()
115 #define sync() EIO_ENOSYS ()
116
117 /* we could even stat and see if it exists */
118 static int
119 symlink (const char *old, const char *neu)
120 {
121 if (CreateSymbolicLink (neu, old, 1))
122 return 0;
123
124 if (CreateSymbolicLink (neu, old, 0))
125 return 0;
126
127 return EIO_ERRNO (ENOENT, -1);
128 }
129
91#else 130#else
92 131
93# include <sys/time.h> 132 #include <sys/time.h>
94# include <sys/select.h> 133 #include <sys/select.h>
134 #include <sys/statvfs.h>
95# include <unistd.h> 135 #include <unistd.h>
96# include <utime.h> 136 #include <utime.h>
97# include <signal.h> 137 #include <signal.h>
98# include <dirent.h> 138 #include <dirent.h>
99 139
100#if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES 140 #if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES
101# include <sys/mman.h> 141 #include <sys/mman.h>
102#endif 142 #endif
103 143
104/* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */ 144 /* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */
105# if __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ 145 #if __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
106# define _DIRENT_HAVE_D_TYPE /* sigh */ 146 #define _DIRENT_HAVE_D_TYPE /* sigh */
107# define D_INO(de) (de)->d_fileno 147 #define D_INO(de) (de)->d_fileno
108# define D_NAMLEN(de) (de)->d_namlen 148 #define D_NAMLEN(de) (de)->d_namlen
109# elif __linux || defined d_ino || _XOPEN_SOURCE >= 600 149 #elif __linux || defined d_ino || _XOPEN_SOURCE >= 600
110# define D_INO(de) (de)->d_ino 150 #define D_INO(de) (de)->d_ino
111# endif 151 #endif
112 152
113#ifdef _D_EXACT_NAMLEN 153 #ifdef _D_EXACT_NAMLEN
114# undef D_NAMLEN 154 #undef D_NAMLEN
115# define D_NAMLEN(de) _D_EXACT_NAMLEN (de) 155 #define D_NAMLEN(de) _D_EXACT_NAMLEN (de)
116#endif 156 #endif
117 157
118# ifdef _DIRENT_HAVE_D_TYPE 158 #ifdef _DIRENT_HAVE_D_TYPE
119# define D_TYPE(de) (de)->d_type 159 #define D_TYPE(de) (de)->d_type
120# endif 160 #endif
121 161
122# ifndef EIO_STRUCT_DIRENT 162 #ifndef EIO_STRUCT_DIRENT
123# define EIO_STRUCT_DIRENT struct dirent 163 #define EIO_STRUCT_DIRENT struct dirent
124# endif 164 #endif
125 165
126#endif 166#endif
127 167
128#if HAVE_SENDFILE 168#if HAVE_SENDFILE
129# if __linux 169# if __linux
381} 421}
382 422
383static void ecb_cold 423static void ecb_cold
384etp_thread_init (void) 424etp_thread_init (void)
385{ 425{
426#if !HAVE_PREADWRITE
427 X_MUTEX_CREATE (preadwritelock);
428#endif
386 X_MUTEX_CREATE (wrklock); 429 X_MUTEX_CREATE (wrklock);
387 X_MUTEX_CREATE (reslock); 430 X_MUTEX_CREATE (reslock);
388 X_MUTEX_CREATE (reqlock); 431 X_MUTEX_CREATE (reqlock);
389 X_COND_CREATE (reqwait); 432 X_COND_CREATE (reqwait);
390} 433}
391 434
392static void ecb_cold 435static void ecb_cold
393etp_atfork_prepare (void) 436etp_atfork_prepare (void)
394{ 437{
395 X_LOCK (wrklock);
396 X_LOCK (reqlock);
397 X_LOCK (reslock);
398#if !HAVE_PREADWRITE
399 X_LOCK (preadwritelock);
400#endif
401} 438}
402 439
403static void ecb_cold 440static void ecb_cold
404etp_atfork_parent (void) 441etp_atfork_parent (void)
405{ 442{
406#if !HAVE_PREADWRITE
407 X_UNLOCK (preadwritelock);
408#endif
409 X_UNLOCK (reslock);
410 X_UNLOCK (reqlock);
411 X_UNLOCK (wrklock);
412} 443}
413 444
414static void ecb_cold 445static void ecb_cold
415etp_atfork_child (void) 446etp_atfork_child (void)
416{ 447{
1051 if (res < 0 && sbytes) 1082 if (res < 0 && sbytes)
1052 res = sbytes; 1083 res = sbytes;
1053 1084
1054# endif 1085# endif
1055 1086
1056#elif defined (_WIN32) 1087#elif defined (_WIN32) && 0
1057 /* does not work, just for documentation of what would need to be done */ 1088 /* does not work, just for documentation of what would need to be done */
1058 /* actually, cannot be done like this, as TransmitFile changes the file offset, */ 1089 /* actually, cannot be done like this, as TransmitFile changes the file offset, */
1059 /* libeio guarantees that the file offset does not change, and windows */ 1090 /* libeio guarantees that the file offset does not change, and windows */
1060 /* has no way to get an independent handle to the same file description */ 1091 /* has no way to get an independent handle to the same file description */
1061 HANDLE h = TO_SOCKET (ifd); 1092 HANDLE h = TO_SOCKET (ifd);
1166 /* round up length */ 1197 /* round up length */
1167 *length = (*length + mask) & ~mask; 1198 *length = (*length + mask) & ~mask;
1168} 1199}
1169 1200
1170#if !_POSIX_MEMLOCK 1201#if !_POSIX_MEMLOCK
1171# define eio__mlockall(a) ((errno = ENOSYS), -1) 1202# define eio__mlockall(a) eio_nosyscall()
1172#else 1203#else
1173 1204
1174static int 1205static int
1175eio__mlockall (int flags) 1206eio__mlockall (int flags)
1176{ 1207{
1190 return mlockall (flags); 1221 return mlockall (flags);
1191} 1222}
1192#endif 1223#endif
1193 1224
1194#if !_POSIX_MEMLOCK_RANGE 1225#if !_POSIX_MEMLOCK_RANGE
1195# define eio__mlock(a,b) ((errno = ENOSYS), -1) 1226# define eio__mlock(a,b) EIO_ENOSYS ()
1196#else 1227#else
1197 1228
1198static int 1229static int
1199eio__mlock (void *addr, size_t length) 1230eio__mlock (void *addr, size_t length)
1200{ 1231{
1204} 1235}
1205 1236
1206#endif 1237#endif
1207 1238
1208#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO) 1239#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO)
1209# define eio__msync(a,b,c) ((errno = ENOSYS), -1) 1240# define eio__msync(a,b,c) EIO_ENOSYS ()
1210#else 1241#else
1211 1242
1212static int 1243static int
1213eio__msync (void *mem, size_t len, int flags) 1244eio__msync (void *mem, size_t len, int flags)
1214{ 1245{
1803X_THREAD_PROC (etp_proc) 1834X_THREAD_PROC (etp_proc)
1804{ 1835{
1805 ETP_REQ *req; 1836 ETP_REQ *req;
1806 struct timespec ts; 1837 struct timespec ts;
1807 etp_worker *self = (etp_worker *)thr_arg; 1838 etp_worker *self = (etp_worker *)thr_arg;
1839 int timeout;
1808 1840
1809 /* try to distribute timeouts somewhat randomly */ 1841 /* try to distribute timeouts somewhat evenly */
1810 ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL); 1842 ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL);
1811 1843
1812 for (;;) 1844 for (;;)
1813 { 1845 {
1846 ts.tv_sec = 0;
1847
1814 X_LOCK (reqlock); 1848 X_LOCK (reqlock);
1815 1849
1816 for (;;) 1850 for (;;)
1817 { 1851 {
1818 self->req = req = reqq_shift (&req_queue); 1852 self->req = req = reqq_shift (&req_queue);
1819 1853
1820 if (req) 1854 if (req)
1821 break; 1855 break;
1822 1856
1857 if (ts.tv_sec == 1) /* no request, but timeout detected, let's quit */
1858 {
1859 X_UNLOCK (reqlock);
1860 X_LOCK (wrklock);
1861 --started;
1862 X_UNLOCK (wrklock);
1863 goto quit;
1864 }
1865
1823 ++idle; 1866 ++idle;
1824 1867
1825 ts.tv_sec = time (0) + idle_timeout; 1868 if (idle <= max_idle)
1826 if (X_COND_TIMEDWAIT (reqwait, reqlock, ts) == ETIMEDOUT) 1869 /* we are allowed to idle, so do so without any timeout */
1870 X_COND_WAIT (reqwait, reqlock);
1871 else
1827 { 1872 {
1828 if (idle > max_idle) 1873 /* initialise timeout once */
1829 { 1874 if (!ts.tv_sec)
1830 --idle; 1875 ts.tv_sec = time (0) + idle_timeout;
1831 X_UNLOCK (reqlock);
1832 X_LOCK (wrklock);
1833 --started;
1834 X_UNLOCK (wrklock);
1835 goto quit;
1836 }
1837 1876
1838 /* we are allowed to idle, so do so without any timeout */
1839 X_COND_WAIT (reqwait, reqlock); 1877 if (X_COND_TIMEDWAIT (reqwait, reqlock, ts) == ETIMEDOUT)
1878 ts.tv_sec = 1; /* assuming this is not a value computed above.,.. */
1840 } 1879 }
1841 1880
1842 --idle; 1881 --idle;
1843 } 1882 }
1844 1883

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines