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

Comparing libeio/eio.c (file contents):
Revision 1.95 by root, Tue Jul 19 04:56:43 2011 UTC vs.
Revision 1.101 by root, Wed Aug 3 15:25:38 2011 UTC

105#ifdef _WIN32 105#ifdef _WIN32
106 106
107 #undef PAGESIZE 107 #undef PAGESIZE
108 #define PAGESIZE 4096 /* GetSystemInfo? */ 108 #define PAGESIZE 4096 /* GetSystemInfo? */
109 109
110 /* TODO: look at how perl does stat (non-sloppy), unlink (ro-files), utime, link */
111
110 #ifdef EIO_STRUCT_STATI64 112 #ifdef EIO_STRUCT_STATI64
113 /* look at perl's non-sloppy stat */
111 #define stat(path,buf) _stati64 (path,buf) 114 #define stat(path,buf) _stati64 (path,buf)
112 #define fstat(fd,buf) _fstati64 (fd,buf) 115 #define fstat(fd,buf) _fstati64 (fd,buf)
113 #endif 116 #endif
114 #define lstat(path,buf) stat (path,buf) 117 #define lstat(path,buf) stat (path,buf)
115 #define fsync(fd) (FlushFileBuffers ((HANDLE)EIO_FD_TO_WIN32_HANDLE (fd)) ? 0 : EIO_ERRNO (EBADF, -1)) 118 #define fsync(fd) (FlushFileBuffers ((HANDLE)EIO_FD_TO_WIN32_HANDLE (fd)) ? 0 : EIO_ERRNO (EBADF, -1))
129 #define sync() EIO_ENOSYS () 132 #define sync() EIO_ENOSYS ()
130 #define readlink(path,buf,s) EIO_ENOSYS () 133 #define readlink(path,buf,s) EIO_ENOSYS ()
131 #define statvfs(path,buf) EIO_ENOSYS () 134 #define statvfs(path,buf) EIO_ENOSYS ()
132 #define fstatvfs(fd,buf) EIO_ENOSYS () 135 #define fstatvfs(fd,buf) EIO_ENOSYS ()
133 136
137 /* rename() uses MoveFile, which fails to overwrite */
138 #define rename(old,neu) eio__rename (old, neu)
139
140 static int
141 eio__rename (const char *old, const char *neu)
142 {
143 if (MoveFileEx (old, neu, MOVEFILE_REPLACE_EXISTING))
144 return 0;
145
146 /* should steal _dosmaperr */
147 switch (GetLastError ())
148 {
149 case ERROR_FILE_NOT_FOUND:
150 case ERROR_PATH_NOT_FOUND:
151 case ERROR_INVALID_DRIVE:
152 case ERROR_NO_MORE_FILES:
153 case ERROR_BAD_NETPATH:
154 case ERROR_BAD_NET_NAME:
155 case ERROR_BAD_PATHNAME:
156 case ERROR_FILENAME_EXCED_RANGE:
157 errno = ENOENT;
158 break;
159
160 default:
161 errno = EACCES;
162 break;
163 }
164
165 return -1;
166 }
167
134 /* we could even stat and see if it exists */ 168 /* we could even stat and see if it exists */
135 static int 169 static int
136 symlink (const char *old, const char *neu) 170 symlink (const char *old, const char *neu)
137 { 171 {
138 #if WINVER >= 0x0600 172 #if WINVER >= 0x0600
164 198
165 #include <sys/time.h> 199 #include <sys/time.h>
166 #include <sys/select.h> 200 #include <sys/select.h>
167 #include <sys/statvfs.h> 201 #include <sys/statvfs.h>
168 #include <unistd.h> 202 #include <unistd.h>
169 #include <utime.h>
170 #include <signal.h> 203 #include <signal.h>
171 #include <dirent.h> 204 #include <dirent.h>
172 205
173 #if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES 206 #if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES
174 #include <sys/mman.h> 207 #include <sys/mman.h>
196 229
197 #ifndef EIO_STRUCT_DIRENT 230 #ifndef EIO_STRUCT_DIRENT
198 #define EIO_STRUCT_DIRENT struct dirent 231 #define EIO_STRUCT_DIRENT struct dirent
199 #endif 232 #endif
200 233
234#endif
235
236#if HAVE_UTIMES
237# include <utime.h>
238#endif
239
240#if HAVE_SYS_SYSCALL_H
241# include <sys/syscall.h>
242#endif
243
244#if HAVE_SYS_PRCTL_H
245# include <sys/prctl.h>
201#endif 246#endif
202 247
203#if HAVE_SENDFILE 248#if HAVE_SENDFILE
204# if __linux 249# if __linux
205# include <sys/sendfile.h> 250# include <sys/sendfile.h>
279static void (*done_poll_cb) (void); 324static void (*done_poll_cb) (void);
280 325
281static unsigned int max_poll_time; /* reslock */ 326static unsigned int max_poll_time; /* reslock */
282static unsigned int max_poll_reqs; /* reslock */ 327static unsigned int max_poll_reqs; /* reslock */
283 328
284static volatile unsigned int nreqs; /* reqlock */ 329static unsigned int nreqs; /* reqlock */
285static volatile unsigned int nready; /* reqlock */ 330static unsigned int nready; /* reqlock */
286static volatile unsigned int npending; /* reqlock */ 331static unsigned int npending; /* reqlock */
287static volatile unsigned int max_idle = 4; /* maximum number of threads that can idle indefinitely */ 332static unsigned int max_idle = 4; /* maximum number of threads that can idle indefinitely */
288static volatile unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */ 333static unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */
289 334
290static xmutex_t wrklock; 335static xmutex_t wrklock;
291static xmutex_t reslock; 336static xmutex_t reslock;
292static xmutex_t reqlock; 337static xmutex_t reqlock;
293static xcond_t reqwait; 338static xcond_t reqwait;
933 978
934#if !HAVE_FDATASYNC 979#if !HAVE_FDATASYNC
935# undef fdatasync 980# undef fdatasync
936# define fdatasync(fd) fsync (fd) 981# define fdatasync(fd) fsync (fd)
937#endif 982#endif
983
984static int
985eio__syncfs (int fd)
986{
987 int res;
988
989#if HAVE_SYS_SYNCFS
990 res = (int)syscall (__NR_syncfs, (int)(fd));
991#else
992 res = -1;
993 errno = ENOSYS;
994#endif
995
996 if (res < 0 && errno == ENOSYS && fd >= 0)
997 sync ();
998
999 return res;
1000}
938 1001
939/* sync_file_range always needs emulation */ 1002/* sync_file_range always needs emulation */
940static int 1003static int
941eio__sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags) 1004eio__sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags)
942{ 1005{
1645 1708
1646 if (dirp == INVALID_HANDLE_VALUE) 1709 if (dirp == INVALID_HANDLE_VALUE)
1647 { 1710 {
1648 dirp = 0; 1711 dirp = 0;
1649 1712
1713 /* should steal _dosmaperr */
1650 switch (GetLastError ()) 1714 switch (GetLastError ())
1651 { 1715 {
1652 case ERROR_FILE_NOT_FOUND: 1716 case ERROR_FILE_NOT_FOUND:
1653 req->result = 0; 1717 req->result = 0;
1654 break; 1718 break;
1888{ 1952{
1889 ETP_REQ *req; 1953 ETP_REQ *req;
1890 struct timespec ts; 1954 struct timespec ts;
1891 etp_worker *self = (etp_worker *)thr_arg; 1955 etp_worker *self = (etp_worker *)thr_arg;
1892 1956
1957#if HAVE_PRCTL_SET_NAME
1958 prctl (PR_SET_NAME, (unsigned long)"eio_thread", 0, 0, 0);
1959#endif
1960
1893 /* try to distribute timeouts somewhat evenly */ 1961 /* try to distribute timeouts somewhat evenly */
1894 ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL); 1962 ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL);
1895 1963
1896 for (;;) 1964 for (;;)
1897 { 1965 {
2064 req->result = readlink (req->ptr1, req->ptr2, PATH_MAX); break; 2132 req->result = readlink (req->ptr1, req->ptr2, PATH_MAX); break;
2065 2133
2066 case EIO_SYNC: req->result = 0; sync (); break; 2134 case EIO_SYNC: req->result = 0; sync (); break;
2067 case EIO_FSYNC: req->result = fsync (req->int1); break; 2135 case EIO_FSYNC: req->result = fsync (req->int1); break;
2068 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; 2136 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
2137 case EIO_SYNCFS: req->result = eio__syncfs (req->int1); break;
2138 case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break;
2069 case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break; 2139 case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break;
2070 case EIO_MTOUCH: req->result = eio__mtouch (req); break; 2140 case EIO_MTOUCH: req->result = eio__mtouch (req); break;
2071 case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break; 2141 case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break;
2072 case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break; 2142 case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break;
2073 case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break;
2074 case EIO_FALLOCATE: req->result = eio__fallocate (req->int1, req->int2, req->offs, req->size); break; 2143 case EIO_FALLOCATE: req->result = eio__fallocate (req->int1, req->int2, req->offs, req->size); break;
2075 2144
2076 case EIO_READDIR: eio__scandir (req, self); break; 2145 case EIO_READDIR: eio__scandir (req, self); break;
2077 2146
2078 case EIO_BUSY: 2147 case EIO_BUSY:
2159eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data) 2228eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
2160{ 2229{
2161 REQ (EIO_MSYNC); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND; 2230 REQ (EIO_MSYNC); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
2162} 2231}
2163 2232
2233eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
2234{
2235 REQ (EIO_FDATASYNC); req->int1 = fd; SEND;
2236}
2237
2238eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data)
2239{
2240 REQ (EIO_SYNCFS); req->int1 = fd; SEND;
2241}
2242
2243eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
2244{
2245 REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND;
2246}
2247
2164eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data) 2248eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
2165{ 2249{
2166 REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND; 2250 REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
2167} 2251}
2168 2252
2174eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data) 2258eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data)
2175{ 2259{
2176 REQ (EIO_MLOCKALL); req->int1 = flags; SEND; 2260 REQ (EIO_MLOCKALL); req->int1 = flags; SEND;
2177} 2261}
2178 2262
2179eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
2180{
2181 REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND;
2182}
2183
2184eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data) 2263eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data)
2185{ 2264{
2186 REQ (EIO_FALLOCATE); req->int1 = fd; req->int2 = mode; req->offs = offset; req->size = len; SEND; 2265 REQ (EIO_FALLOCATE); req->int1 = fd; req->int2 = mode; req->offs = offset; req->size = len; SEND;
2187}
2188
2189eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
2190{
2191 REQ (EIO_FDATASYNC); req->int1 = fd; SEND;
2192} 2266}
2193 2267
2194eio_req *eio_close (int fd, int pri, eio_cb cb, void *data) 2268eio_req *eio_close (int fd, int pri, eio_cb cb, void *data)
2195{ 2269{
2196 REQ (EIO_CLOSE); req->int1 = fd; SEND; 2270 REQ (EIO_CLOSE); req->int1 = fd; SEND;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines