--- IO-AIO/AIO.xs 2011/09/27 00:41:51 1.196 +++ IO-AIO/AIO.xs 2011/09/29 23:06:24 1.203 @@ -343,20 +343,23 @@ static void req_destroy (aio_req req); static void req_cancel (aio_req req); -static void want_poll (void) +static void +want_poll (void) { /* write a dummy byte to the pipe so fh becomes ready */ s_epipe_signal (&respipe); } -static void done_poll (void) +static void +done_poll (void) { /* read any signals sent by the worker threads */ s_epipe_drain (&respipe); } /* must be called at most once */ -static SV *req_sv (aio_req req, HV *stash) +static SV * +req_sv (aio_req req, HV *stash) { if (!req->self) { @@ -370,10 +373,11 @@ 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 SvAIO_REQ (SV *sv) +static aio_req +SvAIO_REQ (SV *sv) { MAGIC *mg; @@ -388,7 +392,8 @@ return mg ? (aio_req)mg->mg_ptr : 0; } -static aio_wd SvAIO_WD (SV *sv) +static aio_wd +SvAIO_WD (SV *sv) { if (!SvROK (sv) || SvSTASH (SvRV (sv)) != aio_wd_stash @@ -398,7 +403,8 @@ return (aio_wd)(long)SvIVX (SvRV (sv)); } -static void aio_grp_feed (aio_req grp) +static void +aio_grp_feed (aio_req grp) { if (grp->sv2 && SvOK (grp->sv2)) { @@ -416,7 +422,8 @@ } } -static void req_submit (eio_req *req) +static void +req_submit (eio_req *req) { eio_submit (req); @@ -433,7 +440,8 @@ } } -static int req_invoke (eio_req *req) +static int +req_invoke (eio_req *req) { if (req->flags & FLAG_SV2_RO_OFF) SvREADONLY_off (req->sv2); @@ -465,7 +473,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: @@ -619,10 +627,12 @@ case EIO_STAT: case EIO_LSTAT: case EIO_FSTAT: - PL_laststype = req->type == EIO_LSTAT ? OP_LSTAT : OP_STAT; - PL_laststatval = req->result; - /* if compilation fails here then perl's Stat_t is not struct _stati64 */ - PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2); + PL_laststype = req->type == EIO_LSTAT ? OP_LSTAT : OP_STAT; + + if (!(PL_laststatval = req->result)) + /* if compilation fails here then perl's Stat_t is not struct _stati64 */ + PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2); + PUSHs (sv_result); break; @@ -666,7 +676,8 @@ return !!SvTRUE (ERRSV); } -static void req_destroy (aio_req req) +static void +req_destroy (aio_req req) { if (req->self) { @@ -683,7 +694,8 @@ Safefree (req); } -static void req_cancel_subs (aio_req grp) +static void +req_cancel_subs (aio_req grp) { if (grp->type != EIO_GROUP) return; @@ -694,13 +706,15 @@ eio_grp_cancel (grp); } -static void create_respipe (void) +static void ecb_cold +create_respipe (void) { if (s_epipe_renew (&respipe)) croak ("IO::AIO: unable to initialize result pipe"); } -static void poll_wait (void) +static void +poll_wait (void) { while (eio_nreqs ()) { @@ -719,7 +733,8 @@ } } -static int poll_cb (void) +static int +poll_cb (void) { for (;;) { @@ -762,7 +777,8 @@ #define MMAP_MAGIC PERL_MAGIC_ext -static int mmap_free (pTHX_ SV *sv, MAGIC *mg) +static int ecb_cold +mmap_free (pTHX_ SV *sv, MAGIC *mg) { int old_errno = errno; munmap (mg->mg_ptr, (size_t)mg->mg_obj); @@ -788,26 +804,35 @@ /*****************************************************************************/ -static SV * get_cb (SV *cb_sv) +static SV * +get_cb (SV *cb_sv) { SvGETMAGIC (cb_sv); 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); + + 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; + + 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; \ @@ -817,10 +842,10 @@ if (GIMME_V != G_VOID) \ XPUSHs (req_sv (req, aio_req_stash)); -static void +ecb_inline void req_set_path (aio_req req, SV *path, SV **wdsv, SV **pathsv, eio_wd *wd, void **ptr) { - if (SvROK (path)) + if (expect_false (SvROK (path))) { AV *av = (AV *)SvRV (path); SV *wdob; @@ -844,13 +869,13 @@ *ptr = SvPVbyte_nolen (*pathsv); } -static void +static void ecb_noinline req_set_path1 (aio_req req, SV *path) { req_set_path (req, path, &req->sv1, &req->sv3, &req->wd, &req->ptr1); } -static void +static void ecb_noinline req_set_fh_or_path (aio_req req, int type_path, int type_fh, SV *fh_or_path) { SV *rv = SvROK (fh_or_path) ? SvRV (fh_or_path) : fh_or_path; @@ -870,9 +895,10 @@ req_set_path1 (req, fh_or_path); break; } - } +XS(boot_IO__AIO) ecb_cold; + MODULE = IO::AIO PACKAGE = IO::AIO PROTOTYPES: ENABLE @@ -1280,8 +1306,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; } @@ -1328,9 +1354,6 @@ void aio_chmod (SV8 *fh_or_path, int mode, SV *callback=&PL_sv_undef) - ALIAS: - aio_chmod = EIO_CHMOD - aio_mkdir = EIO_MKDIR PPCODE: { dREQ; @@ -1361,17 +1384,30 @@ dREQ; req->type = EIO_READDIR; - req->sv1 = newSVsv (pathname); - req->ptr1 = SvPVbyte_nolen (req->sv1); req->int1 = flags | EIO_READDIR_DENTS | EIO_READDIR_CUSTOM1; if (flags & EIO_READDIR_DENTS) req->int1 |= EIO_READDIR_CUSTOM2; + req_set_path1 (req, pathname); + REQ_SEND; } void +aio_mkdir (SV8 *pathname, int mode, SV *callback=&PL_sv_undef) + PPCODE: +{ + dREQ; + + req->type = EIO_MKDIR; + req->int2 = mode; + req_set_path1 (req, pathname); + + REQ_SEND; +} + +void aio_unlink (SV8 *pathname, SV *callback=&PL_sv_undef) ALIAS: aio_unlink = EIO_UNLINK @@ -1396,7 +1432,7 @@ PPCODE: { dREQ; - eio_wd wd2; + eio_wd wd2 = 0; req->type = ix; req_set_path1 (req, oldpath); @@ -1761,11 +1797,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