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

Comparing cvsroot/libeio/eio.c (file contents):
Revision 1.1 by root, Sat May 10 17:16:39 2008 UTC vs.
Revision 1.3 by root, Sun May 11 00:06:25 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 <sched.h>
14#include <dirent.h>
18 15
19#ifndef EIO_FINISH 16#ifndef EIO_FINISH
20# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0 17# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0
21#endif 18#endif
22 19
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)
280 free (req->ptr2); 277 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 {
443 440
444 if (req) 441 if (req)
445 { 442 {
446 --npending; 443 --npending;
447 444
448 if (!res_queue.size) 445 if (!res_queue.size && done_poll_cb)
449 done_poll_cb (); 446 done_poll_cb ();
450 } 447 }
451 448
452 X_UNLOCK (reslock); 449 X_UNLOCK (reslock);
453 450
461 req->int1 = 1; /* mark request as delayed */ 458 req->int1 = 1; /* mark request as delayed */
462 continue; 459 continue;
463 } 460 }
464 else 461 else
465 { 462 {
466 int res = eio_invoke (req); 463 int res = eio_finish (req);
467 if (res) 464 if (res)
468 return res; 465 return res;
469 } 466 }
470 467
471 if (maxreqs && !--maxreqs) 468 if (maxreqs && !--maxreqs)
571 568
572 while (todo > 0) 569 while (todo > 0)
573 { 570 {
574 size_t len = todo < EIO_BUFSIZE ? todo : EIO_BUFSIZE; 571 size_t len = todo < EIO_BUFSIZE ? todo : EIO_BUFSIZE;
575 572
576 pread (fd, aio_buf, len, offset); 573 pread (fd, eio_buf, len, offset);
577 offset += len; 574 offset += len;
578 todo -= len; 575 todo -= len;
579 } 576 }
580 577
581 errno = 0; 578 errno = 0;
917 914
918 X_LOCK (reslock); 915 X_LOCK (reslock);
919 916
920 ++npending; 917 ++npending;
921 918
922 if (!reqq_push (&res_queue, req)) 919 if (!reqq_push (&res_queue, req) && want_poll_cb)
923 want_poll_cb (); 920 want_poll_cb ();
924 921
925 self->req = 0; 922 self->req = 0;
926 worker_clear (self); 923 worker_clear (self);
927 924
936 return 0; 933 return 0;
937} 934}
938 935
939/*****************************************************************************/ 936/*****************************************************************************/
940 937
941static void atfork_prepare (void) 938static void eio_atfork_prepare (void)
942{ 939{
943 X_LOCK (wrklock); 940 X_LOCK (wrklock);
944 X_LOCK (reqlock); 941 X_LOCK (reqlock);
945 X_LOCK (reslock); 942 X_LOCK (reslock);
946#if !HAVE_PREADWRITE 943#if !HAVE_PREADWRITE
949#if !HAVE_READDIR_R 946#if !HAVE_READDIR_R
950 X_LOCK (readdirlock); 947 X_LOCK (readdirlock);
951#endif 948#endif
952} 949}
953 950
954static void atfork_parent (void) 951static void eio_atfork_parent (void)
955{ 952{
956#if !HAVE_READDIR_R 953#if !HAVE_READDIR_R
957 X_UNLOCK (readdirlock); 954 X_UNLOCK (readdirlock);
958#endif 955#endif
959#if !HAVE_PREADWRITE 956#if !HAVE_PREADWRITE
962 X_UNLOCK (reslock); 959 X_UNLOCK (reslock);
963 X_UNLOCK (reqlock); 960 X_UNLOCK (reqlock);
964 X_UNLOCK (wrklock); 961 X_UNLOCK (wrklock);
965} 962}
966 963
967static void atfork_child (void) 964static void eio_atfork_child (void)
968{ 965{
969 eio_req *prv; 966 eio_req *prv;
970 967
971 while (prv = reqq_shift (&req_queue)) 968 while (prv = reqq_shift (&req_queue))
972 eio_destroy (prv); 969 eio_destroy (prv);
989 idle = 0; 986 idle = 0;
990 nreqs = 0; 987 nreqs = 0;
991 nready = 0; 988 nready = 0;
992 npending = 0; 989 npending = 0;
993 990
994 atfork_parent (); 991 eio_atfork_parent ();
995} 992}
996 993
997int eio_init (void (*want_poll)(void), void (*done_poll)(void)) 994int eio_init (void (*want_poll)(void), void (*done_poll)(void))
998{ 995{
999 want_poll_cb = want_poll; 996 want_poll_cb = want_poll;
1008 X_MUTEX_CHECK (readdirlock); 1005 X_MUTEX_CHECK (readdirlock);
1009 1006
1010 X_COND_CHECK (reqwait); 1007 X_COND_CHECK (reqwait);
1011#endif 1008#endif
1012 1009
1013 X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child); 1010 X_THREAD_ATFORK (eio_atfork_prepare, eio_atfork_parent, eio_atfork_child);
1014} 1011}
1015 1012
1016#if 0 1013#if 0
1017 1014
1018eio_req *eio_fsync (int fd, eio_cb cb); 1015eio_req *eio_fsync (int fd, eio_cb cb);
1414{ 1411{
1415 dREQ; 1412 dREQ;
1416 1413
1417#endif 1414#endif
1418 1415
1419void eio_grp_feed (eio_req *grp, int limit, void (*feed)(eio_req *req)) 1416void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit)
1420{ 1417{
1421 grp->int2 = limit; 1418 grp->int2 = limit;
1422 grp->feed = feed; 1419 grp->feed = feed;
1420
1421 grp_try_feed (grp);
1422}
1423
1424void eio_grp_limit (eio_req *grp, int limit)
1425{
1426 grp->int2 = limit;
1427
1428 grp_try_feed (grp);
1423} 1429}
1424 1430
1425void eio_grp_add (eio_req *grp, eio_req *req) 1431void eio_grp_add (eio_req *grp, eio_req *req)
1426{ 1432{
1427 assert (("cannot add requests to IO::AIO::GRP after the group finished", grp->int1 != 2)); 1433 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