--- IO-AIO/AIO.xs 2010/05/04 21:14:01 1.164 +++ IO-AIO/AIO.xs 2010/08/04 17:16:19 1.171 @@ -142,6 +142,44 @@ # 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 PROT_NONE +# define PROT_NONE 0 +#endif +#ifndef PROT_READ +# define PROT_READ 0 +#endif +#ifndef PROT_WRITE +# define PROT_READ 0 +#endif +#ifndef PROT_EXEC +# define PROT_EXEC 0 +#endif + #ifndef ST_NODEV # define ST_NODEV 0 #endif @@ -306,18 +344,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 +523,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 +532,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 +552,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; @@ -589,6 +646,7 @@ #if !_POSIX_MAPPED_FILES # define mmap(addr,length,prot,flags,fd,offs) (errno = ENOSYS, -1) # define munmap(addr,length) (errno = ENOSYS, -1) +# define mprotect(addr,len,prot) (errno = ENOSYS, -1) #endif #define MMAP_MAGIC PERL_MAGIC_ext @@ -603,8 +661,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); @@ -679,6 +740,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) @@ -692,8 +759,8 @@ const_iv (ST_NODIRATIME) const_iv (ST_RELATIME) - const_iv (PROT_EXEC) const_iv (PROT_NONE) + const_iv (PROT_EXEC) const_iv (PROT_READ) const_iv (PROT_WRITE) @@ -1342,11 +1409,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 @@ -1369,14 +1432,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); @@ -1392,6 +1461,36 @@ sv_unmagic (scalar, MMAP_MAGIC); int +madvise (SV *scalar, off_t offset, off_t length, IV advice_or_prot) + ALIAS: + mprotect = 1 + PROTOTYPE: $$$$ + CODE: +{ + STRLEN cur; + char *addr = SvPVbyte (scalar, cur); + + if (offset > cur) + RETVAL = errno = EFAULT; + else + { + if (!SvOK (ST (2))) + length = cur - offset; + + if (offset + length > cur) + RETVAL = errno = EFAULT; + else + switch (ix) + { + case 0: RETVAL = posix_madvise (addr + offset, length, advice_or_prot); break; + case 1: RETVAL = mprotect (addr + offset, length, advice_or_prot); break; + } + } +} + OUTPUT: + RETVAL + +int mlockall (int flags) PROTOTYPE: $ CODE: