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

Comparing libeio/eio.c (file contents):
Revision 1.4 by root, Sun May 11 00:10:15 2008 UTC vs.
Revision 1.8 by root, Sun May 11 20:08:37 2008 UTC

8#include <errno.h> 8#include <errno.h>
9#include <sys/types.h> 9#include <sys/types.h>
10#include <sys/stat.h> 10#include <sys/stat.h>
11#include <limits.h> 11#include <limits.h>
12#include <fcntl.h> 12#include <fcntl.h>
13#include <sched.h> 13#include <assert.h>
14 14
15#ifndef EIO_FINISH 15#ifndef EIO_FINISH
16# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0 16# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0
17#endif 17#endif
18 18
271 return 0; 271 return 0;
272} 272}
273 273
274void eio_destroy (eio_req *req) 274void eio_destroy (eio_req *req)
275{ 275{
276 if ((req)->flags & EIO_FLAG_PTR1_FREE) free (req->ptr1);
276 if ((req)->flags & EIO_FLAG_PTR2_FREE) 277 if ((req)->flags & EIO_FLAG_PTR2_FREE) free (req->ptr2);
277 free (req->ptr2);
278 278
279 EIO_DESTROY (req); 279 EIO_DESTROY (req);
280} 280}
281 281
282static int eio_finish (eio_req *req) 282static int eio_finish (eio_req *req)
312 eio_cancel (grp); 312 eio_cancel (grp);
313} 313}
314 314
315void eio_cancel (eio_req *req) 315void eio_cancel (eio_req *req)
316{ 316{
317 X_LOCK (wrklock);
317 req->flags |= EIO_FLAG_CANCELLED; 318 req->flags |= EIO_FLAG_CANCELLED;
319 X_UNLOCK (wrklock);
318 320
319 eio_grp_cancel (req); 321 eio_grp_cancel (req);
320} 322}
321 323
322X_THREAD_PROC (eio_proc); 324X_THREAD_PROC (eio_proc);
323 325
324static void start_thread (void) 326static void start_thread (void)
325{ 327{
326 worker *wrk = calloc (1, sizeof (worker)); 328 worker *wrk = calloc (1, sizeof (worker));
327 329
328 if (!wrk) 330 /*TODO*/
329 croak ("unable to allocate worker thread data"); 331 assert (("unable to allocate worker thread data", !wrk));
330 332
331 X_LOCK (wrklock); 333 X_LOCK (wrklock);
332 334
333 if (thread_create (&wrk->tid, eio_proc, (void *)wrk)) 335 if (thread_create (&wrk->tid, eio_proc, (void *)wrk))
334 { 336 {
584#if !HAVE_READDIR_R 586#if !HAVE_READDIR_R
585# define readdir_r aio_readdir_r 587# define readdir_r aio_readdir_r
586 588
587static mutex_t readdirlock = X_MUTEX_INIT; 589static mutex_t readdirlock = X_MUTEX_INIT;
588 590
589static int readdir_r (DIR *dirp, X_DIRENT *ent, X_DIRENT **res) 591static int readdir_r (DIR *dirp, EIO_STRUCT_DIRENT *ent, EIO_STRUCT_DIRENT **res)
590{ 592{
591 X_DIRENT *e; 593 EIO_STRUCT_DIRENT *e;
592 int errorno; 594 int errorno;
593 595
594 X_LOCK (readdirlock); 596 X_LOCK (readdirlock);
595 597
596 e = readdir (dirp); 598 e = readdir (dirp);
765 req->result = res; 767 req->result = res;
766} 768}
767 769
768/*****************************************************************************/ 770/*****************************************************************************/
769 771
772#define ALLOC(len) \
773 if (!req->ptr2) \
774 { \
775 X_LOCK (wrklock); \
776 req->flags |= EIO_FLAG_PTR2_FREE; \
777 X_UNLOCK (wrklock); \
778 req->ptr2 = malloc (len); \
779 if (!req->ptr2) \
780 { \
781 errno = ENOMEM; \
782 req->result = -1; \
783 break; \
784 } \
785 }
786
770X_THREAD_PROC (eio_proc) 787X_THREAD_PROC (eio_proc)
771{ 788{
772 eio_req *req; 789 eio_req *req;
773 struct timespec ts; 790 struct timespec ts;
774 worker *self = (worker *)thr_arg; 791 worker *self = (worker *)thr_arg;
818 errno = 0; /* strictly unnecessary */ 835 errno = 0; /* strictly unnecessary */
819 836
820 if (!EIO_CANCELLED (req)) 837 if (!EIO_CANCELLED (req))
821 switch (req->type) 838 switch (req->type)
822 { 839 {
840 case EIO_READ: ALLOC (req->size);
823 case EIO_READ: req->result = req->offs >= 0 841 req->result = req->offs >= 0
824 ? pread (req->int1, req->ptr2, req->size, req->offs) 842 ? pread (req->int1, req->ptr2, req->size, req->offs)
825 : read (req->int1, req->ptr2, req->size); break; 843 : read (req->int1, req->ptr2, req->size); break;
826 case EIO_WRITE: req->result = req->offs >= 0 844 case EIO_WRITE: req->result = req->offs >= 0
827 ? pwrite (req->int1, req->ptr2, req->size, req->offs) 845 ? pwrite (req->int1, req->ptr2, req->size, req->offs)
828 : write (req->int1, req->ptr2, req->size); break; 846 : write (req->int1, req->ptr2, req->size); break;
829 847
830 case EIO_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; 848 case EIO_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break;
831 case EIO_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break; 849 case EIO_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break;
832 850
851 case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT));
833 case EIO_STAT: req->result = stat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break; 852 req->result = stat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break;
853 case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT));
834 case EIO_LSTAT: req->result = lstat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break; 854 req->result = lstat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break;
855 case EIO_FSTAT: ALLOC (sizeof (EIO_STRUCT_STAT));
835 case EIO_FSTAT: req->result = fstat (req->int1, (EIO_STRUCT_STAT *)req->ptr2); break; 856 req->result = fstat (req->int1, (EIO_STRUCT_STAT *)req->ptr2); break;
836 857
837 case EIO_CHOWN: req->result = chown (req->ptr1, req->int2, req->int3); break; 858 case EIO_CHOWN: req->result = chown (req->ptr1, req->int2, req->int3); break;
838 case EIO_FCHOWN: req->result = fchown (req->int1, req->int2, req->int3); break; 859 case EIO_FCHOWN: req->result = fchown (req->int1, req->int2, req->int3); break;
839 case EIO_CHMOD: req->result = chmod (req->ptr1, (mode_t)req->int2); break; 860 case EIO_CHMOD: req->result = chmod (req->ptr1, (mode_t)req->int2); break;
840 case EIO_FCHMOD: req->result = fchmod (req->int1, (mode_t)req->int2); break; 861 case EIO_FCHMOD: req->result = fchmod (req->int1, (mode_t)req->int2); break;
849 case EIO_MKDIR: req->result = mkdir (req->ptr1, (mode_t)req->int2); break; 870 case EIO_MKDIR: req->result = mkdir (req->ptr1, (mode_t)req->int2); break;
850 case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break; 871 case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break;
851 case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break; 872 case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break;
852 case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break; 873 case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break;
853 case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->offs); break; 874 case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->offs); break;
875
876 case EIO_READLINK: ALLOC (NAME_MAX);
854 case EIO_READLINK: req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break; 877 req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break;
855 878
856 case EIO_SYNC: req->result = 0; sync (); break; 879 case EIO_SYNC: req->result = 0; sync (); break;
857 case EIO_FSYNC: req->result = fsync (req->int1); break; 880 case EIO_FSYNC: req->result = fsync (req->int1); break;
858 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; 881 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
859 882
1008#endif 1031#endif
1009 1032
1010 X_THREAD_ATFORK (eio_atfork_prepare, eio_atfork_parent, eio_atfork_child); 1033 X_THREAD_ATFORK (eio_atfork_prepare, eio_atfork_parent, eio_atfork_child);
1011} 1034}
1012 1035
1036static void eio_api_destroy (eio_req *req)
1037{
1038 free (req);
1039}
1040
1041#define REQ(rtype) \
1042 eio_req *req; \
1043 \
1044 req = (eio_req *)calloc (1, sizeof *req); \
1045 if (!req) \
1046 return 0; \
1047 \
1048 req->type = EIO_ ## rtype; \
1049 req->pri = EIO_DEFAULT_PRI + EIO_PRI_BIAS; \
1050 req->finish = cb; \
1051 req->destroy = eio_api_destroy;
1052
1053#define SEND eio_submit (req); return req
1054
1055#define PATH (void)0
1056
1057eio_req *eio_fsync (int fd, eio_cb cb)
1058{
1059 REQ (FSYNC); req->int1 = fd; SEND;
1060}
1061
1062eio_req *eio_fdatasync (int fd, eio_cb cb)
1063{
1064 REQ (FDATASYNC); req->int1 = fd; SEND;
1065}
1066
1067eio_req *eio_readahead (int fd, off_t offset, size_t length, eio_cb cb)
1068{
1069 REQ (READAHEAD); req->int1 = fd; req->offs = offset; req->size = length; SEND;
1070}
1071
1072eio_req *eio_read (int fd, off_t offset, size_t length, void *data, eio_cb cb)
1073{
1074 REQ (READ); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = data; SEND;
1075}
1076
1077eio_req *eio_write (int fd, off_t offset, size_t length, void *data, eio_cb cb)
1078{
1079 REQ (WRITE); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = data; SEND;
1080}
1081
1082eio_req *eio_fstat (int fd, eio_cb cb)
1083{
1084 REQ (FSTAT); req->int1 = fd; SEND;
1085}
1086
1087eio_req *eio_futime (int fd, double atime, double mtime, eio_cb cb)
1088{
1089 REQ (FUTIME); req->int1 = fd; req->nv1 = atime; req->nv2 = mtime; SEND;
1090}
1091
1092eio_req *eio_ftruncate (int fd, off_t offset, eio_cb cb)
1093{
1094 REQ (FTRUNCATE); req->int1 = fd; req->offs = offset; SEND;
1095}
1096
1097eio_req *eio_fchmod (int fd, mode_t mode, eio_cb cb)
1098{
1099 REQ (FCHMOD); req->int1 = fd; req->int2 = (long)mode; SEND;
1100}
1101
1102eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, eio_cb cb)
1103{
1104 REQ (FCHOWN); req->int1 = fd; req->int2 = (long)uid; req->int3 = (long)gid; SEND;
1105}
1106
1107eio_req *eio_dup2 (int fd, int fd2, eio_cb cb)
1108{
1109 REQ (DUP2); req->int1 = fd; req->int2 = fd2; SEND;
1110}
1111
1112eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, eio_cb cb)
1113{
1114 REQ (SENDFILE); req->int1 = out_fd; req->int2 = in_fd; req->offs = in_offset; req->size = length; SEND;
1115}
1116
1117eio_req *eio_open (const char *path, int flags, mode_t mode, eio_cb cb)
1118{
1119 REQ (OPEN); PATH; req->int1 = flags; req->int2 = (long)mode; SEND;
1120}
1121
1122eio_req *eio_readlink (const char *path, eio_cb cb)
1123{
1124 REQ (READLINK); PATH; SEND;
1125}
1126
1127eio_req *eio_stat (const char *path, eio_cb cb)
1128{
1129 REQ (STAT); PATH; SEND;
1130}
1131
1132eio_req *eio_lstat (const char *path, eio_cb cb)
1133{
1134 REQ (LSTAT); PATH; SEND;
1135}
1136
1137eio_req *eio_utime (const char *path, double atime, double mtime, eio_cb cb)
1138{
1139 REQ (UTIME); PATH; req->nv1 = atime; req->nv2 = mtime; SEND;
1140}
1141
1142eio_req *eio_truncate (const char *path, off_t offset, eio_cb cb)
1143{
1144 REQ (TRUNCATE); PATH; req->offs = offset; SEND;
1145}
1146
1147eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, eio_cb cb)
1148{
1149 REQ (CHOWN); PATH; req->int2 = (long)uid; req->int3 = (long)gid; SEND;
1150}
1151
1152eio_req *eio_chmod (const char *path, mode_t mode, eio_cb cb)
1153{
1154 REQ (CHMOD); PATH; req->int2 = (long)mode; SEND;
1155}
1156
1157eio_req *eio_mkdir (const char *path, mode_t mode, eio_cb cb)
1158{
1159 REQ (MKDIR); PATH; req->int2 = (long)mode; SEND;
1160}
1161
1162eio_req *eio_unlink (const char *path, eio_cb cb)
1163{
1164 REQ (UNLINK); PATH; SEND;
1165}
1166
1167eio_req *eio_rmdir (const char *path, eio_cb cb)
1168{
1169 REQ (RMDIR); PATH; SEND;
1170}
1171
1172eio_req *eio_readdir (const char *path, eio_cb cb)
1173{
1174 REQ (READDIR); PATH; SEND;
1175}
1176
1177eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, eio_cb cb)
1178{
1179 REQ (MKNOD); PATH; req->int2 = (long)mode; req->int2 = (long)dev; SEND;
1180}
1181
1182eio_req *eio_busy (double delay, eio_cb cb)
1183{
1184 REQ (BUSY); req->nv1 = delay; SEND;
1185}
1186
1187eio_req *eio_nop (eio_cb cb)
1188{
1189 REQ (NOP); SEND;
1190}
1191
1192#undef REQ
1193#undef PATH
1194#undef SEND
1195
1013#if 0 1196#if 0
1014 1197
1015eio_req *eio_fsync (int fd, eio_cb cb);
1016eio_req *eio_fdatasync (int fd, eio_cb cb);
1017eio_req *eio_dupclose (int fd, eio_cb cb);
1018eio_req *eio_readahead (int fd, off_t offset, size_t length, eio_cb cb);
1019eio_req *eio_read (int fd, off_t offs, size_t length, char *data, eio_cb cb);
1020eio_req *eio_write (int fd, off_t offs, size_t length, char *data, eio_cb cb);
1021eio_req *eio_fstat (int fd, eio_cb cb); /* stat buffer=ptr2 allocates dynamically */
1022eio_req *eio_futime (int fd, double atime, double mtime, eio_cb cb);
1023eio_req *eio_ftruncate (int fd, off_t offset, eio_cb cb);
1024eio_req *eio_fchmod (int fd, mode_t mode, eio_cb cb);
1025eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, eio_cb cb);
1026eio_req *eio_dup2 (int fd, int fd2, eio_cb cb);
1027eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, eio_cb cb);
1028eio_req *eio_open (const char *path, int flags, mode_t mode, eio_cb cb);
1029eio_req *eio_readlink (const char *path, eio_cb cb); /* result=ptr2 allocated dynamically */
1030eio_req *eio_stat (const char *path, eio_cb cb); /* stat buffer=ptr2 allocates dynamically */
1031eio_req *eio_lstat (const char *path, eio_cb cb); /* stat buffer=ptr2 allocates dynamically */
1032eio_req *eio_utime (const char *path, double atime, double mtime, eio_cb cb);
1033eio_req *eio_truncate (const char *path, off_t offset, eio_cb cb);
1034eio_req *eio_chmod (const char *path, mode_t mode, eio_cb cb);
1035eio_req *eio_mkdir (const char *path, mode_t mode, eio_cb cb);
1036eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, eio_cb cb);
1037eio_req *eio_unlink (const char *path, eio_cb cb);
1038eio_req *eio_rmdir (const char *path, eio_cb cb);
1039eio_req *eio_readdir (const char *path, eio_cb cb); /* result=ptr2 allocated dynamically */
1040eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, eio_cb cb);
1041eio_req *eio_busy (double delay, eio_cb cb); /* ties a thread for this long, simulating busyness */
1042eio_req *eio_nop (eio_cb cb); /* does nothing except go through the whole process */
1043void 1198void
1044aio_open (SV8 *pathname, int flags, int mode, SV *callback=&PL_sv_undef) 1199aio_open (SV8 *pathname, int flags, int mode, SV *callback=&PL_sv_undef)
1045 PROTOTYPE: $$$;$ 1200 PROTOTYPE: $$$;$
1046 PPCODE: 1201 PPCODE:
1047{ 1202{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines