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

Comparing libeio/eio.c (file contents):
Revision 1.1 by root, Sat May 10 17:16:39 2008 UTC vs.
Revision 1.8 by root, Sun May 11 20:08:37 2008 UTC

1#include "eio.h" 1#include "eio.h"
2#include "xthread.h" 2#include "xthread.h"
3 3
4#include <errno.h> 4#include <errno.h>
5
6#include "EXTERN.h"
7#include "perl.h"
8#include "XSUB.h"
9
10#include <stddef.h> 5#include <stddef.h>
11#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h>
12#include <errno.h> 8#include <errno.h>
13#include <sys/types.h> 9#include <sys/types.h>
14#include <sys/stat.h> 10#include <sys/stat.h>
15#include <limits.h> 11#include <limits.h>
16#include <fcntl.h> 12#include <fcntl.h>
17#include <sched.h> 13#include <assert.h>
18 14
19#ifndef EIO_FINISH 15#ifndef EIO_FINISH
20# 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
21#endif 17#endif
22 18
38# include <sys/time.h> 34# include <sys/time.h>
39# include <sys/select.h> 35# include <sys/select.h>
40# include <unistd.h> 36# include <unistd.h>
41# include <utime.h> 37# include <utime.h>
42# include <signal.h> 38# include <signal.h>
39# include <dirent.h>
43 40
44# ifndef EIO_STRUCT_DIRENT 41# ifndef EIO_STRUCT_DIRENT
45# define EIO_STRUCT_DIRENT struct dirent 42# define EIO_STRUCT_DIRENT struct dirent
46# endif 43# endif
47 44
239 } 236 }
240 237
241 abort (); 238 abort ();
242} 239}
243 240
244static void grp_feed (eio_req *grp) 241static void grp_try_feed (eio_req *grp)
245{ 242{
246 while (grp->size < grp->int2 && !EIO_CANCELLED (grp)) 243 while (grp->size < grp->int2 && !EIO_CANCELLED (grp))
247 { 244 {
248 int old_len = grp->size; 245 int old_len = grp->size;
249 246
251 248
252 /* stop if no progress has been made */ 249 /* stop if no progress has been made */
253 if (old_len == grp->size) 250 if (old_len == grp->size)
254 { 251 {
255 grp->feed = 0; 252 grp->feed = 0;
256 grp->int2 = 0; 253 break;
257 } 254 }
258 } 255 }
259} 256}
260 257
261static int eio_invoke (eio_req *req); 258static int eio_finish (eio_req *req);
262 259
263static int grp_dec (eio_req *grp) 260static int grp_dec (eio_req *grp)
264{ 261{
265 --grp->size; 262 --grp->size;
266 263
267 /* call feeder, if applicable */ 264 /* call feeder, if applicable */
268 grp_feed (grp); 265 grp_try_feed (grp);
269 266
270 /* finish, if done */ 267 /* finish, if done */
271 if (!grp->size && grp->int1) 268 if (!grp->size && grp->int1)
272 return eio_invoke (grp); 269 return eio_finish (grp);
273 else 270 else
274 return 0; 271 return 0;
275} 272}
276 273
277void eio_destroy (eio_req *req) 274void eio_destroy (eio_req *req)
278{ 275{
276 if ((req)->flags & EIO_FLAG_PTR1_FREE) free (req->ptr1);
279 if ((req)->flags & EIO_FLAG_PTR2_FREE) 277 if ((req)->flags & EIO_FLAG_PTR2_FREE) free (req->ptr2);
280 free (req->ptr2);
281 278
282 EIO_DESTROY (req); 279 EIO_DESTROY (req);
283} 280}
284 281
285static int eio_invoke (eio_req *req) 282static int eio_finish (eio_req *req)
286{ 283{
287 int res = EIO_FINISH (req); 284 int res = EIO_FINISH (req);
288 285
289 if (req->grp) 286 if (req->grp)
290 { 287 {
315 eio_cancel (grp); 312 eio_cancel (grp);
316} 313}
317 314
318void eio_cancel (eio_req *req) 315void eio_cancel (eio_req *req)
319{ 316{
317 X_LOCK (wrklock);
320 req->flags |= EIO_FLAG_CANCELLED; 318 req->flags |= EIO_FLAG_CANCELLED;
319 X_UNLOCK (wrklock);
321 320
322 eio_grp_cancel (req); 321 eio_grp_cancel (req);
323} 322}
324 323
325X_THREAD_PROC (eio_proc); 324X_THREAD_PROC (eio_proc);
326 325
327static void start_thread (void) 326static void start_thread (void)
328{ 327{
329 worker *wrk = calloc (1, sizeof (worker)); 328 worker *wrk = calloc (1, sizeof (worker));
330 329
331 if (!wrk) 330 /*TODO*/
332 croak ("unable to allocate worker thread data"); 331 assert (("unable to allocate worker thread data", !wrk));
333 332
334 X_LOCK (wrklock); 333 X_LOCK (wrklock);
335 334
336 if (thread_create (&wrk->tid, eio_proc, (void *)wrk)) 335 if (thread_create (&wrk->tid, eio_proc, (void *)wrk))
337 { 336 {
443 442
444 if (req) 443 if (req)
445 { 444 {
446 --npending; 445 --npending;
447 446
448 if (!res_queue.size) 447 if (!res_queue.size && done_poll_cb)
449 done_poll_cb (); 448 done_poll_cb ();
450 } 449 }
451 450
452 X_UNLOCK (reslock); 451 X_UNLOCK (reslock);
453 452
461 req->int1 = 1; /* mark request as delayed */ 460 req->int1 = 1; /* mark request as delayed */
462 continue; 461 continue;
463 } 462 }
464 else 463 else
465 { 464 {
466 int res = eio_invoke (req); 465 int res = eio_finish (req);
467 if (res) 466 if (res)
468 return res; 467 return res;
469 } 468 }
470 469
471 if (maxreqs && !--maxreqs) 470 if (maxreqs && !--maxreqs)
571 570
572 while (todo > 0) 571 while (todo > 0)
573 { 572 {
574 size_t len = todo < EIO_BUFSIZE ? todo : EIO_BUFSIZE; 573 size_t len = todo < EIO_BUFSIZE ? todo : EIO_BUFSIZE;
575 574
576 pread (fd, aio_buf, len, offset); 575 pread (fd, eio_buf, len, offset);
577 offset += len; 576 offset += len;
578 todo -= len; 577 todo -= len;
579 } 578 }
580 579
581 errno = 0; 580 errno = 0;
587#if !HAVE_READDIR_R 586#if !HAVE_READDIR_R
588# define readdir_r aio_readdir_r 587# define readdir_r aio_readdir_r
589 588
590static mutex_t readdirlock = X_MUTEX_INIT; 589static mutex_t readdirlock = X_MUTEX_INIT;
591 590
592static 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)
593{ 592{
594 X_DIRENT *e; 593 EIO_STRUCT_DIRENT *e;
595 int errorno; 594 int errorno;
596 595
597 X_LOCK (readdirlock); 596 X_LOCK (readdirlock);
598 597
599 e = readdir (dirp); 598 e = readdir (dirp);
768 req->result = res; 767 req->result = res;
769} 768}
770 769
771/*****************************************************************************/ 770/*****************************************************************************/
772 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
773X_THREAD_PROC (eio_proc) 787X_THREAD_PROC (eio_proc)
774{ 788{
775 eio_req *req; 789 eio_req *req;
776 struct timespec ts; 790 struct timespec ts;
777 worker *self = (worker *)thr_arg; 791 worker *self = (worker *)thr_arg;
821 errno = 0; /* strictly unnecessary */ 835 errno = 0; /* strictly unnecessary */
822 836
823 if (!EIO_CANCELLED (req)) 837 if (!EIO_CANCELLED (req))
824 switch (req->type) 838 switch (req->type)
825 { 839 {
840 case EIO_READ: ALLOC (req->size);
826 case EIO_READ: req->result = req->offs >= 0 841 req->result = req->offs >= 0
827 ? pread (req->int1, req->ptr2, req->size, req->offs) 842 ? pread (req->int1, req->ptr2, req->size, req->offs)
828 : read (req->int1, req->ptr2, req->size); break; 843 : read (req->int1, req->ptr2, req->size); break;
829 case EIO_WRITE: req->result = req->offs >= 0 844 case EIO_WRITE: req->result = req->offs >= 0
830 ? pwrite (req->int1, req->ptr2, req->size, req->offs) 845 ? pwrite (req->int1, req->ptr2, req->size, req->offs)
831 : write (req->int1, req->ptr2, req->size); break; 846 : write (req->int1, req->ptr2, req->size); break;
832 847
833 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;
834 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;
835 850
851 case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT));
836 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));
837 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));
838 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;
839 857
840 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;
841 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;
842 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;
843 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;
852 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;
853 case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break; 871 case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break;
854 case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break; 872 case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break;
855 case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break; 873 case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break;
856 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);
857 case EIO_READLINK: req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break; 877 req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break;
858 878
859 case EIO_SYNC: req->result = 0; sync (); break; 879 case EIO_SYNC: req->result = 0; sync (); break;
860 case EIO_FSYNC: req->result = fsync (req->int1); break; 880 case EIO_FSYNC: req->result = fsync (req->int1); break;
861 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; 881 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
862 882
917 937
918 X_LOCK (reslock); 938 X_LOCK (reslock);
919 939
920 ++npending; 940 ++npending;
921 941
922 if (!reqq_push (&res_queue, req)) 942 if (!reqq_push (&res_queue, req) && want_poll_cb)
923 want_poll_cb (); 943 want_poll_cb ();
924 944
925 self->req = 0; 945 self->req = 0;
926 worker_clear (self); 946 worker_clear (self);
927 947
936 return 0; 956 return 0;
937} 957}
938 958
939/*****************************************************************************/ 959/*****************************************************************************/
940 960
941static void atfork_prepare (void) 961static void eio_atfork_prepare (void)
942{ 962{
943 X_LOCK (wrklock); 963 X_LOCK (wrklock);
944 X_LOCK (reqlock); 964 X_LOCK (reqlock);
945 X_LOCK (reslock); 965 X_LOCK (reslock);
946#if !HAVE_PREADWRITE 966#if !HAVE_PREADWRITE
949#if !HAVE_READDIR_R 969#if !HAVE_READDIR_R
950 X_LOCK (readdirlock); 970 X_LOCK (readdirlock);
951#endif 971#endif
952} 972}
953 973
954static void atfork_parent (void) 974static void eio_atfork_parent (void)
955{ 975{
956#if !HAVE_READDIR_R 976#if !HAVE_READDIR_R
957 X_UNLOCK (readdirlock); 977 X_UNLOCK (readdirlock);
958#endif 978#endif
959#if !HAVE_PREADWRITE 979#if !HAVE_PREADWRITE
962 X_UNLOCK (reslock); 982 X_UNLOCK (reslock);
963 X_UNLOCK (reqlock); 983 X_UNLOCK (reqlock);
964 X_UNLOCK (wrklock); 984 X_UNLOCK (wrklock);
965} 985}
966 986
967static void atfork_child (void) 987static void eio_atfork_child (void)
968{ 988{
969 eio_req *prv; 989 eio_req *prv;
970 990
971 while (prv = reqq_shift (&req_queue)) 991 while (prv = reqq_shift (&req_queue))
972 eio_destroy (prv); 992 eio_destroy (prv);
989 idle = 0; 1009 idle = 0;
990 nreqs = 0; 1010 nreqs = 0;
991 nready = 0; 1011 nready = 0;
992 npending = 0; 1012 npending = 0;
993 1013
994 atfork_parent (); 1014 eio_atfork_parent ();
995} 1015}
996 1016
997int eio_init (void (*want_poll)(void), void (*done_poll)(void)) 1017int eio_init (void (*want_poll)(void), void (*done_poll)(void))
998{ 1018{
999 want_poll_cb = want_poll; 1019 want_poll_cb = want_poll;
1008 X_MUTEX_CHECK (readdirlock); 1028 X_MUTEX_CHECK (readdirlock);
1009 1029
1010 X_COND_CHECK (reqwait); 1030 X_COND_CHECK (reqwait);
1011#endif 1031#endif
1012 1032
1013 X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child); 1033 X_THREAD_ATFORK (eio_atfork_prepare, eio_atfork_parent, eio_atfork_child);
1014} 1034}
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
1015 1195
1016#if 0 1196#if 0
1017 1197
1018eio_req *eio_fsync (int fd, eio_cb cb);
1019eio_req *eio_fdatasync (int fd, eio_cb cb);
1020eio_req *eio_dupclose (int fd, eio_cb cb);
1021eio_req *eio_readahead (int fd, off_t offset, size_t length, eio_cb cb);
1022eio_req *eio_read (int fd, off_t offs, size_t length, char *data, eio_cb cb);
1023eio_req *eio_write (int fd, off_t offs, size_t length, char *data, eio_cb cb);
1024eio_req *eio_fstat (int fd, eio_cb cb); /* stat buffer=ptr2 allocates dynamically */
1025eio_req *eio_futime (int fd, double atime, double mtime, eio_cb cb);
1026eio_req *eio_ftruncate (int fd, off_t offset, eio_cb cb);
1027eio_req *eio_fchmod (int fd, mode_t mode, eio_cb cb);
1028eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, eio_cb cb);
1029eio_req *eio_dup2 (int fd, int fd2, eio_cb cb);
1030eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, eio_cb cb);
1031eio_req *eio_open (const char *path, int flags, mode_t mode, eio_cb cb);
1032eio_req *eio_readlink (const char *path, eio_cb cb); /* result=ptr2 allocated dynamically */
1033eio_req *eio_stat (const char *path, eio_cb cb); /* stat buffer=ptr2 allocates dynamically */
1034eio_req *eio_lstat (const char *path, eio_cb cb); /* stat buffer=ptr2 allocates dynamically */
1035eio_req *eio_utime (const char *path, double atime, double mtime, eio_cb cb);
1036eio_req *eio_truncate (const char *path, off_t offset, eio_cb cb);
1037eio_req *eio_chmod (const char *path, mode_t mode, eio_cb cb);
1038eio_req *eio_mkdir (const char *path, mode_t mode, eio_cb cb);
1039eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, eio_cb cb);
1040eio_req *eio_unlink (const char *path, eio_cb cb);
1041eio_req *eio_rmdir (const char *path, eio_cb cb);
1042eio_req *eio_readdir (const char *path, eio_cb cb); /* result=ptr2 allocated dynamically */
1043eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, eio_cb cb);
1044eio_req *eio_busy (double delay, eio_cb cb); /* ties a thread for this long, simulating busyness */
1045eio_req *eio_nop (eio_cb cb); /* does nothing except go through the whole process */
1046void 1198void
1047aio_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)
1048 PROTOTYPE: $$$;$ 1200 PROTOTYPE: $$$;$
1049 PPCODE: 1201 PPCODE:
1050{ 1202{
1414{ 1566{
1415 dREQ; 1567 dREQ;
1416 1568
1417#endif 1569#endif
1418 1570
1419void eio_grp_feed (eio_req *grp, int limit, void (*feed)(eio_req *req)) 1571void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit)
1420{ 1572{
1421 grp->int2 = limit; 1573 grp->int2 = limit;
1422 grp->feed = feed; 1574 grp->feed = feed;
1575
1576 grp_try_feed (grp);
1577}
1578
1579void eio_grp_limit (eio_req *grp, int limit)
1580{
1581 grp->int2 = limit;
1582
1583 grp_try_feed (grp);
1423} 1584}
1424 1585
1425void eio_grp_add (eio_req *grp, eio_req *req) 1586void eio_grp_add (eio_req *grp, eio_req *req)
1426{ 1587{
1427 assert (("cannot add requests to IO::AIO::GRP after the group finished", grp->int1 != 2)); 1588 assert (("cannot add requests to IO::AIO::GRP after the group finished", grp->int1 != 2));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines