--- IO-AIO/AIO.xs 2010/01/10 23:44:02 1.163 +++ IO-AIO/AIO.xs 2010/08/04 16:09:36 1.170 @@ -142,6 +142,31 @@ # define POSIX_FADV_DONTNEED 0 #endif +#if _XOPEN_SOURCE < 600 || NO_FADVISE +# define posix_fadvise(a,b,c,d) errno = ENOSYS /* also return ENOSYS */ +#endif + +#ifndef POSIX_MADV_NORMAL +# define POSIX_MADV_NORMAL 0 +# define NO_MADVISE 1 +#endif +#ifndef POSIX_MADV_SEQUENTIAL +# define POSIX_MADV_SEQUENTIAL 0 +#endif +#ifndef POSIX_MADV_RANDOM +# define POSIX_MADV_RANDOM 0 +#endif +#ifndef POSIX_MADV_WILLNEED +# define POSIX_MADV_WILLNEED 0 +#endif +#ifndef POSIX_MADV_DONTNEED +# define POSIX_MADV_DONTNEED 0 +#endif + +#if _XOPEN_SOURCE < 600 || NO_MADVISE +# define posix_madvise(a,b,c) errno = ENOSYS /* also return ENOSYS */ +#endif + #ifndef ST_NODEV # define ST_NODEV 0 #endif @@ -306,18 +331,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 +510,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 +519,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 +539,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; @@ -603,8 +647,11 @@ mg->mg_obj = 0; /* just in case */ SvREADONLY_off (sv); + + if (SvPVX (sv) != mg->mg_ptr) + croak ("ERROR: IO::AIO::mmap-mapped scalar changed location, detected"); + SvCUR_set (sv, 0); - SvLEN_set (sv, 0); SvPVX (sv) = 0; SvOK_off (sv); @@ -664,8 +711,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 @@ -676,6 +726,12 @@ const_niv (FADV_WILLNEED , POSIX_FADV_WILLNEED) const_niv (FADV_DONTNEED , POSIX_FADV_DONTNEED) + const_niv (MADV_NORMAL , POSIX_MADV_NORMAL) + const_niv (MADV_SEQUENTIAL, POSIX_MADV_SEQUENTIAL) + const_niv (MADV_RANDOM , POSIX_MADV_RANDOM) + const_niv (MADV_WILLNEED , POSIX_MADV_WILLNEED) + const_niv (MADV_DONTNEED , POSIX_MADV_DONTNEED) + const_iv (ST_RDONLY) const_iv (ST_NOSUID) const_iv (ST_NODEV) @@ -1339,11 +1395,7 @@ fadvise (aio_rfd fh, off_t offset, off_t length, IV advice) PROTOTYPE: $$$$ CODE: -#if _XOPEN_SOURCE >= 600 && !NO_FADVISE RETVAL = posix_fadvise (fh, offset, length, advice); -#else - RETVAL = errno = ENOSYS; /* yes, this is actually correct */ -#endif OUTPUT: RETVAL @@ -1366,14 +1418,20 @@ if (addr == (void *)-1) XSRETURN_NO; + sv_force_normal (scalar); + /* we store the length in mg_obj, as namlen is I32 :/ */ sv_magicext (scalar, 0, MMAP_MAGIC, &mmap_vtbl, (char *)addr, 0) ->mg_obj = (SV *)length; SvUPGRADE (scalar, SVt_PV); /* nop... */ + if (!(prot & PROT_WRITE)) SvREADONLY_on (scalar); + if (SvLEN (scalar)) + Safefree (SvPVX (scalar)); + SvPVX (scalar) = (char *)addr; SvCUR_set (scalar, length); SvLEN_set (scalar, 0); @@ -1389,6 +1447,24 @@ sv_unmagic (scalar, MMAP_MAGIC); int +madvise (SV *scalar, off_t offset, off_t length, IV advice) + PROTOTYPE: $$$$ + CODE: +{ + char *addr = SvPV_nolen (scalar) + offset; + + if (!SvOK (ST (2))) + length = SvCUR (scalar) - offset; + + if (addr >= SvEND (scalar) || length <= 0) + XSRETURN_EMPTY; + + RETVAL = posix_madvise (addr, length, advice); +} + OUTPUT: + RETVAL + +int mlockall (int flags) PROTOTYPE: $ CODE: