… | |
… | |
239 | } |
239 | } |
240 | |
240 | |
241 | abort (); |
241 | abort (); |
242 | } |
242 | } |
243 | |
243 | |
244 | static void grp_feed (eio_req *grp) |
244 | static void grp_try_feed (eio_req *grp) |
245 | { |
245 | { |
246 | while (grp->size < grp->int2 && !EIO_CANCELLED (grp)) |
246 | while (grp->size < grp->int2 && !EIO_CANCELLED (grp)) |
247 | { |
247 | { |
248 | int old_len = grp->size; |
248 | int old_len = grp->size; |
249 | |
249 | |
… | |
… | |
251 | |
251 | |
252 | /* stop if no progress has been made */ |
252 | /* stop if no progress has been made */ |
253 | if (old_len == grp->size) |
253 | if (old_len == grp->size) |
254 | { |
254 | { |
255 | grp->feed = 0; |
255 | grp->feed = 0; |
256 | grp->int2 = 0; |
256 | break; |
257 | } |
257 | } |
258 | } |
258 | } |
259 | } |
259 | } |
260 | |
260 | |
261 | static int eio_invoke (eio_req *req); |
261 | static int eio_finish (eio_req *req); |
262 | |
262 | |
263 | static int grp_dec (eio_req *grp) |
263 | static int grp_dec (eio_req *grp) |
264 | { |
264 | { |
265 | --grp->size; |
265 | --grp->size; |
266 | |
266 | |
267 | /* call feeder, if applicable */ |
267 | /* call feeder, if applicable */ |
268 | grp_feed (grp); |
268 | grp_try_feed (grp); |
269 | |
269 | |
270 | /* finish, if done */ |
270 | /* finish, if done */ |
271 | if (!grp->size && grp->int1) |
271 | if (!grp->size && grp->int1) |
272 | return eio_invoke (grp); |
272 | return eio_finish (grp); |
273 | else |
273 | else |
274 | return 0; |
274 | return 0; |
275 | } |
275 | } |
276 | |
276 | |
277 | void eio_destroy (eio_req *req) |
277 | void eio_destroy (eio_req *req) |
… | |
… | |
280 | free (req->ptr2); |
280 | free (req->ptr2); |
281 | |
281 | |
282 | EIO_DESTROY (req); |
282 | EIO_DESTROY (req); |
283 | } |
283 | } |
284 | |
284 | |
285 | static int eio_invoke (eio_req *req) |
285 | static int eio_finish (eio_req *req) |
286 | { |
286 | { |
287 | int res = EIO_FINISH (req); |
287 | int res = EIO_FINISH (req); |
288 | |
288 | |
289 | if (req->grp) |
289 | if (req->grp) |
290 | { |
290 | { |
… | |
… | |
443 | |
443 | |
444 | if (req) |
444 | if (req) |
445 | { |
445 | { |
446 | --npending; |
446 | --npending; |
447 | |
447 | |
448 | if (!res_queue.size) |
448 | if (!res_queue.size && done_poll_cb) |
449 | done_poll_cb (); |
449 | done_poll_cb (); |
450 | } |
450 | } |
451 | |
451 | |
452 | X_UNLOCK (reslock); |
452 | X_UNLOCK (reslock); |
453 | |
453 | |
… | |
… | |
461 | req->int1 = 1; /* mark request as delayed */ |
461 | req->int1 = 1; /* mark request as delayed */ |
462 | continue; |
462 | continue; |
463 | } |
463 | } |
464 | else |
464 | else |
465 | { |
465 | { |
466 | int res = eio_invoke (req); |
466 | int res = eio_finish (req); |
467 | if (res) |
467 | if (res) |
468 | return res; |
468 | return res; |
469 | } |
469 | } |
470 | |
470 | |
471 | if (maxreqs && !--maxreqs) |
471 | if (maxreqs && !--maxreqs) |
… | |
… | |
917 | |
917 | |
918 | X_LOCK (reslock); |
918 | X_LOCK (reslock); |
919 | |
919 | |
920 | ++npending; |
920 | ++npending; |
921 | |
921 | |
922 | if (!reqq_push (&res_queue, req)) |
922 | if (!reqq_push (&res_queue, req) && want_poll_cb) |
923 | want_poll_cb (); |
923 | want_poll_cb (); |
924 | |
924 | |
925 | self->req = 0; |
925 | self->req = 0; |
926 | worker_clear (self); |
926 | worker_clear (self); |
927 | |
927 | |
… | |
… | |
936 | return 0; |
936 | return 0; |
937 | } |
937 | } |
938 | |
938 | |
939 | /*****************************************************************************/ |
939 | /*****************************************************************************/ |
940 | |
940 | |
941 | static void atfork_prepare (void) |
941 | static void eio_atfork_prepare (void) |
942 | { |
942 | { |
943 | X_LOCK (wrklock); |
943 | X_LOCK (wrklock); |
944 | X_LOCK (reqlock); |
944 | X_LOCK (reqlock); |
945 | X_LOCK (reslock); |
945 | X_LOCK (reslock); |
946 | #if !HAVE_PREADWRITE |
946 | #if !HAVE_PREADWRITE |
… | |
… | |
949 | #if !HAVE_READDIR_R |
949 | #if !HAVE_READDIR_R |
950 | X_LOCK (readdirlock); |
950 | X_LOCK (readdirlock); |
951 | #endif |
951 | #endif |
952 | } |
952 | } |
953 | |
953 | |
954 | static void atfork_parent (void) |
954 | static void eio_atfork_parent (void) |
955 | { |
955 | { |
956 | #if !HAVE_READDIR_R |
956 | #if !HAVE_READDIR_R |
957 | X_UNLOCK (readdirlock); |
957 | X_UNLOCK (readdirlock); |
958 | #endif |
958 | #endif |
959 | #if !HAVE_PREADWRITE |
959 | #if !HAVE_PREADWRITE |
… | |
… | |
962 | X_UNLOCK (reslock); |
962 | X_UNLOCK (reslock); |
963 | X_UNLOCK (reqlock); |
963 | X_UNLOCK (reqlock); |
964 | X_UNLOCK (wrklock); |
964 | X_UNLOCK (wrklock); |
965 | } |
965 | } |
966 | |
966 | |
967 | static void atfork_child (void) |
967 | static void eio_atfork_child (void) |
968 | { |
968 | { |
969 | eio_req *prv; |
969 | eio_req *prv; |
970 | |
970 | |
971 | while (prv = reqq_shift (&req_queue)) |
971 | while (prv = reqq_shift (&req_queue)) |
972 | eio_destroy (prv); |
972 | eio_destroy (prv); |
… | |
… | |
989 | idle = 0; |
989 | idle = 0; |
990 | nreqs = 0; |
990 | nreqs = 0; |
991 | nready = 0; |
991 | nready = 0; |
992 | npending = 0; |
992 | npending = 0; |
993 | |
993 | |
994 | atfork_parent (); |
994 | eio_atfork_parent (); |
995 | } |
995 | } |
996 | |
996 | |
997 | int eio_init (void (*want_poll)(void), void (*done_poll)(void)) |
997 | int eio_init (void (*want_poll)(void), void (*done_poll)(void)) |
998 | { |
998 | { |
999 | want_poll_cb = want_poll; |
999 | want_poll_cb = want_poll; |
… | |
… | |
1008 | X_MUTEX_CHECK (readdirlock); |
1008 | X_MUTEX_CHECK (readdirlock); |
1009 | |
1009 | |
1010 | X_COND_CHECK (reqwait); |
1010 | X_COND_CHECK (reqwait); |
1011 | #endif |
1011 | #endif |
1012 | |
1012 | |
1013 | X_THREAD_ATFORK (atfork_prepare, atfork_parent, atfork_child); |
1013 | X_THREAD_ATFORK (eio_atfork_prepare, eio_atfork_parent, eio_atfork_child); |
1014 | } |
1014 | } |
1015 | |
1015 | |
1016 | #if 0 |
1016 | #if 0 |
1017 | |
1017 | |
1018 | eio_req *eio_fsync (int fd, eio_cb cb); |
1018 | eio_req *eio_fsync (int fd, eio_cb cb); |
… | |
… | |
1414 | { |
1414 | { |
1415 | dREQ; |
1415 | dREQ; |
1416 | |
1416 | |
1417 | #endif |
1417 | #endif |
1418 | |
1418 | |
1419 | void eio_grp_feed (eio_req *grp, int limit, void (*feed)(eio_req *req)) |
1419 | void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit) |
1420 | { |
1420 | { |
1421 | grp->int2 = limit; |
1421 | grp->int2 = limit; |
1422 | grp->feed = feed; |
1422 | grp->feed = feed; |
|
|
1423 | |
|
|
1424 | grp_try_feed (grp); |
|
|
1425 | } |
|
|
1426 | |
|
|
1427 | void eio_grp_limit (eio_req *grp, int limit) |
|
|
1428 | { |
|
|
1429 | grp->int2 = limit; |
|
|
1430 | |
|
|
1431 | grp_try_feed (grp); |
1423 | } |
1432 | } |
1424 | |
1433 | |
1425 | void eio_grp_add (eio_req *grp, eio_req *req) |
1434 | void eio_grp_add (eio_req *grp, eio_req *req) |
1426 | { |
1435 | { |
1427 | assert (("cannot add requests to IO::AIO::GRP after the group finished", grp->int1 != 2)); |
1436 | assert (("cannot add requests to IO::AIO::GRP after the group finished", grp->int1 != 2)); |