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

Comparing libeio/eio.c (file contents):
Revision 1.17 by root, Tue Jun 3 05:12:51 2008 UTC vs.
Revision 1.23 by root, Sun Sep 21 00:23:45 2008 UTC

177static mutex_t wrklock = X_MUTEX_INIT; 177static mutex_t wrklock = X_MUTEX_INIT;
178static mutex_t reslock = X_MUTEX_INIT; 178static mutex_t reslock = X_MUTEX_INIT;
179static mutex_t reqlock = X_MUTEX_INIT; 179static mutex_t reqlock = X_MUTEX_INIT;
180static cond_t reqwait = X_COND_INIT; 180static cond_t reqwait = X_COND_INIT;
181 181
182#if !HAVE_PREADWRITE
183/*
184 * make our pread/pwrite emulation safe against themselves, but not against
185 * normal read/write by using a mutex. slows down execution a lot,
186 * but that's your problem, not mine.
187 */
188static mutex_t preadwritelock = X_MUTEX_INIT;
189#endif
190
182typedef struct etp_worker 191typedef struct etp_worker
183{ 192{
184 /* locked by wrklock */ 193 /* locked by wrklock */
185 struct etp_worker *prev, *next; 194 struct etp_worker *prev, *next;
186 195
330 339
331static void etp_atfork_child (void) 340static void etp_atfork_child (void)
332{ 341{
333 ETP_REQ *prv; 342 ETP_REQ *prv;
334 343
335 while (prv = reqq_shift (&req_queue)) 344 while ((prv = reqq_shift (&req_queue)))
336 ETP_DESTROY (prv); 345 ETP_DESTROY (prv);
337 346
338 while (prv = reqq_shift (&res_queue)) 347 while ((prv = reqq_shift (&res_queue)))
339 ETP_DESTROY (prv); 348 ETP_DESTROY (prv);
340 349
341 while (wrk_first.next != &wrk_first) 350 while (wrk_first.next != &wrk_first)
342 { 351 {
343 etp_worker *wrk = wrk_first.next; 352 etp_worker *wrk = wrk_first.next;
371 380
372 pthread_once (&doinit, etp_once_init); 381 pthread_once (&doinit, etp_once_init);
373 382
374 want_poll_cb = want_poll; 383 want_poll_cb = want_poll;
375 done_poll_cb = done_poll; 384 done_poll_cb = done_poll;
385
386 return 0;
376} 387}
377 388
378X_THREAD_PROC (etp_proc); 389X_THREAD_PROC (etp_proc);
379 390
380static void etp_start_thread (void) 391static void etp_start_thread (void)
698 709
699#if !HAVE_PREADWRITE 710#if !HAVE_PREADWRITE
700# define pread eio__pread 711# define pread eio__pread
701# define pwrite eio__pwrite 712# define pwrite eio__pwrite
702 713
703/*
704 * make our pread/pwrite safe against themselves, but not against
705 * normal read/write by using a mutex. slows down execution a lot,
706 * but that's your problem, not mine.
707 */
708static mutex_t preadwritelock = X_MUTEX_INIT;
709
710static ssize_t 714static ssize_t
711eio__pread (int fd, void *buf, size_t count, off_t offset) 715eio__pread (int fd, void *buf, size_t count, off_t offset)
712{ 716{
713 ssize_t res; 717 ssize_t res;
714 off_t ooffset; 718 off_t ooffset;
901 int memlen = 4096; 905 int memlen = 4096;
902 int memofs = 0; 906 int memofs = 0;
903 int res = 0; 907 int res = 0;
904 908
905 X_LOCK (wrklock); 909 X_LOCK (wrklock);
910 /* the corresponding closedir is in ETP_WORKER_CLEAR */
906 self->dirp = dirp = opendir (req->ptr1); 911 self->dirp = dirp = opendir (req->ptr1);
907 req->flags |= EIO_FLAG_PTR2_FREE; 912 req->flags |= EIO_FLAG_PTR2_FREE;
908 req->ptr2 = names = malloc (memlen); 913 req->ptr2 = names = malloc (memlen);
909 X_UNLOCK (wrklock); 914 X_UNLOCK (wrklock);
910 915
943 948
944 if (errno) 949 if (errno)
945 res = -1; 950 res = -1;
946 951
947 req->result = res; 952 req->result = res;
953}
954
955#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO)
956# define msync(a,b,c) ENOSYS
957#endif
958
959int
960eio__mtouch (void *mem, size_t len, int flags)
961{
962 intptr_t addr = (intptr_t)mem;
963 intptr_t end = addr + len;
964#ifdef PAGESIZE
965 const intptr_t page = PAGESIZE;
966#else
967 static intptr_t page;
968
969 if (!page)
970 page = sysconf (_SC_PAGESIZE);
971#endif
972
973 addr &= ~(page - 1); /* assume page size is always a power of two */
974
975 if (addr < end)
976 if (flags) /* modify */
977 do { *((volatile sig_atomic_t *)addr) |= 0; } while ((addr += page) < len);
978 else
979 do { *((volatile sig_atomic_t *)addr) ; } while ((addr += page) < len);
980
981 return 0;
948} 982}
949 983
950/*****************************************************************************/ 984/*****************************************************************************/
951 985
952#define ALLOC(len) \ 986#define ALLOC(len) \
1039 1073
1040/*****************************************************************************/ 1074/*****************************************************************************/
1041 1075
1042int eio_init (void (*want_poll)(void), void (*done_poll)(void)) 1076int eio_init (void (*want_poll)(void), void (*done_poll)(void))
1043{ 1077{
1044 etp_init (want_poll, done_poll); 1078 return etp_init (want_poll, done_poll);
1045} 1079}
1046 1080
1047static void eio_api_destroy (eio_req *req) 1081static void eio_api_destroy (eio_req *req)
1048{ 1082{
1049 free (req); 1083 free (req);
1111 case EIO_RMDIR: req->result = rmdir (req->ptr1); break; 1145 case EIO_RMDIR: req->result = rmdir (req->ptr1); break;
1112 case EIO_MKDIR: req->result = mkdir (req->ptr1, (mode_t)req->int2); break; 1146 case EIO_MKDIR: req->result = mkdir (req->ptr1, (mode_t)req->int2); break;
1113 case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break; 1147 case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break;
1114 case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break; 1148 case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break;
1115 case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break; 1149 case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break;
1116 case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->offs); break; 1150 case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->int3); break;
1117 1151
1118 case EIO_READLINK: ALLOC (NAME_MAX); 1152 case EIO_READLINK: ALLOC (NAME_MAX);
1119 req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break; 1153 req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break;
1120 1154
1121 case EIO_SYNC: req->result = 0; sync (); break; 1155 case EIO_SYNC: req->result = 0; sync (); break;
1122 case EIO_FSYNC: req->result = fsync (req->int1); break; 1156 case EIO_FSYNC: req->result = fsync (req->int1); break;
1123 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; 1157 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
1158 case EIO_MSYNC: req->result = msync (req->ptr2, req->size, req->int1); break;
1159 case EIO_MTOUCH: req->result = eio__mtouch (req->ptr2, req->size, req->int1); break;
1124 1160
1125 case EIO_READDIR: eio__scandir (req, self); break; 1161 case EIO_READDIR: eio__scandir (req, self); break;
1126 1162
1127 case EIO_BUSY: 1163 case EIO_BUSY:
1128#ifdef _WIN32 1164#ifdef _WIN32
1167 case EIO_NOP: 1203 case EIO_NOP:
1168 req->result = 0; 1204 req->result = 0;
1169 break; 1205 break;
1170 1206
1171 case EIO_CUSTOM: 1207 case EIO_CUSTOM:
1172 req->feed (req); 1208 ((void (*)(eio_req *))req->feed) (req);
1173 break; 1209 break;
1174 1210
1175 default: 1211 default:
1176 req->result = -1; 1212 req->result = -1;
1177 break; 1213 break;
1200eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data) 1236eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data)
1201{ 1237{
1202 REQ (EIO_FSYNC); req->int1 = fd; SEND; 1238 REQ (EIO_FSYNC); req->int1 = fd; SEND;
1203} 1239}
1204 1240
1241eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
1242{
1243 REQ (EIO_MSYNC); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
1244}
1245
1246eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
1247{
1248 REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
1249}
1250
1205eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data) 1251eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
1206{ 1252{
1207 REQ (EIO_FDATASYNC); req->int1 = fd; SEND; 1253 REQ (EIO_FDATASYNC); req->int1 = fd; SEND;
1208} 1254}
1209 1255
1328 return eio__1path (EIO_READDIR, path, pri, cb, data); 1374 return eio__1path (EIO_READDIR, path, pri, cb, data);
1329} 1375}
1330 1376
1331eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data) 1377eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data)
1332{ 1378{
1333 REQ (EIO_MKNOD); PATH; req->int2 = (long)mode; req->int2 = (long)dev; SEND; 1379 REQ (EIO_MKNOD); PATH; req->int2 = (long)mode; req->int3 = (long)dev; SEND;
1334} 1380}
1335 1381
1336static eio_req * 1382static eio_req *
1337eio__2path (int type, const char *path, const char *new_path, int pri, eio_cb cb, void *data) 1383eio__2path (int type, const char *path, const char *new_path, int pri, eio_cb cb, void *data)
1338{ 1384{
1364 return eio__2path (EIO_RENAME, path, new_path, pri, cb, data); 1410 return eio__2path (EIO_RENAME, path, new_path, pri, cb, data);
1365} 1411}
1366 1412
1367eio_req *eio_custom (eio_cb execute, int pri, eio_cb cb, void *data) 1413eio_req *eio_custom (eio_cb execute, int pri, eio_cb cb, void *data)
1368{ 1414{
1369 REQ (EIO_CUSTOM); req->feed = execute; SEND; 1415 REQ (EIO_CUSTOM); req->feed = (void (*)(eio_req *))execute; SEND;
1370} 1416}
1371 1417
1372#endif 1418#endif
1373 1419
1374eio_req *eio_grp (eio_cb cb, void *data) 1420eio_req *eio_grp (eio_cb cb, void *data)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines