--- IO-AIO/AIO.xs 2011/09/29 10:01:35 1.202 +++ IO-AIO/AIO.xs 2011/10/01 10:53:47 1.205 @@ -373,7 +373,7 @@ static SV * newSVaio_wd (aio_wd wd) { - return sv_bless (newRV_noinc (newSViv ((long)wd)), aio_wd_stash); + return sv_bless (newRV_noinc (newSViv ((IV)wd)), aio_wd_stash); } static aio_req @@ -382,6 +382,7 @@ MAGIC *mg; if (!SvROK (sv) + /* for speed reasons, we do not verify that SvROK actually has a stash ptr */ || (SvSTASH (SvRV (sv)) != aio_grp_stash && SvSTASH (SvRV (sv)) != aio_req_stash && !sv_derived_from (sv, "IO::AIO::REQ"))) @@ -396,8 +397,8 @@ SvAIO_WD (SV *sv) { if (!SvROK (sv) - || SvSTASH (SvRV (sv)) != aio_wd_stash - || SvTYPE (SvRV (sv)) != SVt_PVMG) + || SvTYPE (SvRV (sv)) != SVt_PVMG + || SvSTASH (SvRV (sv)) != aio_wd_stash) croak ("IO::AIO: expected a working directory object as returned by aio_wd"); return (aio_wd)(long)SvIVX (SvRV (sv)); @@ -473,7 +474,7 @@ switch (req->type) { case EIO_WD_OPEN: - PUSHs (sv_2mortal (newSVaio_wd (req->wd))); + PUSHs (req->result ? &PL_sv_undef : sv_2mortal (newSVaio_wd (req->wd))); break; case EIO_READDIR: @@ -691,7 +692,7 @@ SvREFCNT_dec (req->sv4); SvREFCNT_dec (req->callback); - Safefree (req); + free (req); } static void @@ -811,20 +812,28 @@ return SvOK (cb_sv) ? s_get_cv_croak (cb_sv) : 0; } +static aio_req ecb_noinline +dreq (SV *callback) +{ + SV *cb_cv; + aio_req req; + int req_pri = next_pri; + next_pri = EIO_PRI_DEFAULT; + + cb_cv = get_cb (callback); + + req = calloc (sizeof (*req), 1); + if (!req) + croak ("out of memory during eio_req allocation"); + + req->callback = SvREFCNT_inc (cb_cv); + req->pri = req_pri; + + return req; +} + #define dREQ \ - SV *cb_cv; \ - aio_req req; \ - int req_pri = next_pri; \ - next_pri = EIO_PRI_DEFAULT; \ - \ - cb_cv = get_cb (callback); \ - \ - Newz (0, req, 1, eio_req); \ - if (!req) \ - croak ("out of memory during eio_req allocation"); \ - \ - req->callback = SvREFCNT_inc (cb_cv); \ - req->pri = req_pri + aio_req req = dreq (callback); \ #define REQ_SEND \ PUTBACK; \ @@ -839,22 +848,31 @@ { if (expect_false (SvROK (path))) { - AV *av = (AV *)SvRV (path); + SV *rv = SvRV (path); SV *wdob; - if (SvTYPE (av) != SVt_PVAV || AvFILLp (av) != 1) - croak ("IO::AIO: pathname arguments must be specified as strings or [wd, path] arrayrefs"); - - path = AvARRAY (av)[1]; - wdob = AvARRAY (av)[0]; + if (SvTYPE (rv) == SVt_PVAV && AvFILLp (rv) == 1) + { + path = AvARRAY (rv)[1]; + wdob = AvARRAY (rv)[0]; - if (SvOK (wdob)) + if (SvOK (wdob)) + { + *wd = SvAIO_WD (wdob); + *wdsv = SvREFCNT_inc_NN (SvRV (wdob)); + } + else + *wd = EIO_INVALID_WD; + } + else if (SvTYPE (rv) == SVt_PVMG && SvSTASH (rv) == aio_wd_stash) { - *wd = SvAIO_WD (wdob); - *wdsv = SvREFCNT_inc_NN (SvRV (wdob)); + *wd = SvIVX (rv); + *wdsv = SvREFCNT_inc_NN (rv); + *ptr = "."; + return; /* path set to "." */ } else - *wd = EIO_INVALID_WD; + croak ("IO::AIO: pathname arguments must be specified as a string, an IO::AIO::WD object or a [IO::AIO::WD, path] pair"); } *pathsv = newSVsv (path); @@ -1298,8 +1316,8 @@ { dREQ; - req->sv1 = newSVsv (fh_or_path); req_set_fh_or_path (req, ix, ix == EIO_STATVFS ? EIO_FSTATVFS : EIO_FSTAT, fh_or_path); + REQ_SEND; } @@ -1789,11 +1807,15 @@ { aio_wd wd = SvAIO_WD (self); #if HAVE_AT - SV *callback = &PL_sv_undef; - dREQ; /* clobbers next_pri :/ */ - req->type = EIO_WD_CLOSE; - req->wd = wd; - REQ_SEND; + { + SV *callback = &PL_sv_undef; + dREQ; /* clobbers next_pri :/ */ + next_pri = req->pri; /* restore next_pri */ + req->pri = EIO_PRI_MAX; /* better use max. priority to conserve fds */ + req->type = EIO_WD_CLOSE; + req->wd = wd; + REQ_SEND; + } #else eio_wd_close_sync (wd); #endif