--- IO-AIO/AIO.xs 2005/08/16 22:22:18 1.22 +++ IO-AIO/AIO.xs 2005/08/17 03:52:20 1.26 @@ -33,7 +33,7 @@ REQ_READ, REQ_WRITE, REQ_READAHEAD, REQ_STAT, REQ_LSTAT, REQ_FSTAT, REQ_FSYNC, REQ_FDATASYNC, - REQ_UNLINK, REQ_RMDIR, REQ_SYMLINK, + REQ_UNLINK, REQ_RMDIR, REQ_SYMLINK, }; @@ -70,6 +70,23 @@ static volatile aio_req reqs, reqe; /* queue start, queue end */ static volatile aio_req ress, rese; /* queue start, queue end */ +static void free_req (aio_req req) +{ + if (req->data) + SvREFCNT_dec (req->data); + + if (req->fh) + SvREFCNT_dec (req->fh); + + if (req->type == REQ_STAT || req->type == REQ_LSTAT || req->type == REQ_FSTAT) + Safefree (req->statdata); + + if (req->callback) + SvREFCNT_dec (req->callback); + + Safefree (req); +} + static void poll_wait () { @@ -88,6 +105,7 @@ { dSP; int count = 0; + int do_croak = 0; aio_req req, prv; pthread_mutex_lock (&reslock); @@ -119,19 +137,11 @@ SvCUR_set (req->data, req->dataoffset + req->result > 0 ? req->result : 0); - if (req->data) - SvREFCNT_dec (req->data); - - if (req->fh) - SvREFCNT_dec (req->fh); - if (req->type == REQ_STAT || req->type == REQ_LSTAT || req->type == REQ_FSTAT) { PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT; PL_laststatval = req->result; PL_statcache = *(req->statdata); - - Safefree (req->statdata); } ENTER; @@ -161,19 +171,19 @@ } LEAVE; - - if (req->callback) - SvREFCNT_dec (req->callback); + do_croak = SvTRUE (ERRSV); + errno = errorno; count++; } prv = req; req = req->next; - Safefree (prv); + free_req (prv); - /* TODO: croak on errors? */ + if (do_croak) + croak (0); } return count; @@ -232,7 +242,7 @@ end_thread (void) { aio_req req; - New (0, req, 1, aio_cb); + Newz (0, req, 1, aio_cb); req->type = REQ_QUIT; send_req (req); @@ -261,54 +271,61 @@ } } -static int fork_started; - -static void atfork_prepare (void) +static void create_pipe () { - pthread_mutex_lock (&frklock); - - fork_started = started; + if (pipe (respipe)) + croak ("unable to initialize result pipe"); - for (;;) { - while (nreqs) - { - poll_wait (); - poll_cb (); - } + if (fcntl (respipe [0], F_SETFL, O_NONBLOCK)) + croak ("cannot set result pipe to nonblocking mode"); - max_parallel (0); - - pthread_mutex_lock (&reqlock); - - if (!nreqs && !started) - break; - - pthread_mutex_unlock (&reqlock); - - min_parallel (fork_started); - } + if (fcntl (respipe [1], F_SETFL, O_NONBLOCK)) + croak ("cannot set result pipe to nonblocking mode"); +} +static void atfork_prepare (void) +{ + pthread_mutex_lock (&frklock); + pthread_mutex_lock (&reqlock); pthread_mutex_lock (&reslock); - - assert (!started); - assert (!nreqs); - assert (!reqs && !reqe); - assert (!ress && !rese); } static void atfork_parent (void) { pthread_mutex_unlock (&reslock); - min_parallel (fork_started); pthread_mutex_unlock (&reqlock); pthread_mutex_unlock (&frklock); } static void atfork_child (void) { + int restart = started; + started = 0; + + while (reqs) + { + free_req (reqs); + reqs = reqs->next; + } + reqs = reqe = 0; + while (ress) + { + free_req (ress); + ress = ress->next; + } + + ress = rese = 0; + + close (respipe [0]); + close (respipe [1]); + + create_pipe (); + atfork_parent (); + + min_parallel (restart); } /*****************************************************************************/ @@ -489,15 +506,7 @@ BOOT: { - if (pipe (respipe)) - croak ("unable to initialize result pipe"); - - if (fcntl (respipe [0], F_SETFL, O_NONBLOCK)) - croak ("cannot set result pipe to nonblocking mode"); - - if (fcntl (respipe [1], F_SETFL, O_NONBLOCK)) - croak ("cannot set result pipe to nonblocking mode"); - + create_pipe (); pthread_atfork (atfork_prepare, atfork_parent, atfork_child); }