--- IO-AIO/AIO.xs 2010/01/10 23:44:02 1.163 +++ IO-AIO/AIO.xs 2010/05/09 20:49:52 1.167 @@ -306,18 +306,32 @@ static int req_invoke (eio_req *req) { - dSP; - if (req->flags & FLAG_SV2_RO_OFF) SvREADONLY_off (req->sv2); if (!EIO_CANCELLED (req) && req->callback) { + dSP; + static SV *sv_result_cache; /* caches the result integer SV */ + SV *sv_result; + ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 1); + /* do not recreate the result IV from scratch each time */ + if (expect_true (sv_result_cache)) + { + sv_result = sv_result_cache; sv_result_cache = 0; + SvIV_set (sv_result, req->result); + } + else + { + sv_result = newSViv (req->result); + SvREADONLY_on (sv_result); + } + switch (req->type) { case EIO_READDIR: @@ -471,7 +485,7 @@ PL_laststype = req->type == EIO_LSTAT ? OP_LSTAT : OP_STAT; PL_laststatval = req->result; PL_statcache = *(EIO_STRUCT_STAT *)(req->ptr2); - PUSHs (sv_2mortal (newSViv (req->result))); + PUSHs (sv_result); break; case EIO_READ: @@ -480,17 +494,17 @@ *SvEND (req->sv2) = 0; SvPOK_only (req->sv2); SvSETMAGIC (req->sv2); - PUSHs (sv_2mortal (newSViv (req->result))); + PUSHs (sv_result); } break; - case EIO_DUP2: + case EIO_DUP2: /* EIO_DUP2 actually means aio_close(), su fudge result value */ if (req->result > 0) - req->result = 0; + SvIV_set (sv_result, 0); /* FALLTHROUGH */ default: - PUSHs (sv_2mortal (newSViv (req->result))); + PUSHs (sv_result); break; } @@ -500,6 +514,11 @@ call_sv (req->callback, G_VOID | G_EVAL | G_DISCARD); SPAGAIN; + if (expect_false (SvREFCNT (sv_result) != 1 || sv_result_cache)) + SvREFCNT_dec (sv_result); + else + sv_result_cache = sv_result; + FREETMPS; LEAVE; @@ -664,8 +683,11 @@ const_iv (ENOSYS) const_iv (O_RDONLY) const_iv (O_WRONLY) + const_iv (O_RDWR) const_iv (O_CREAT) const_iv (O_TRUNC) + const_iv (O_EXCL) + const_iv (O_APPEND) #ifndef _WIN32 const_iv (S_IFIFO) #endif