--- IO-AIO/AIO.xs 2008/09/30 17:03:53 1.129 +++ IO-AIO/AIO.xs 2009/04/21 20:06:05 1.138 @@ -113,8 +113,6 @@ static int req_invoke (eio_req *req); #define EIO_FINISH(req) req_invoke (req) -static void aio_grp_feed (eio_req *grp); -#define EIO_FEED(req) aio_grp_feed (req) static void req_destroy (eio_req *grp); #define EIO_DESTROY(req) req_destroy (req) @@ -316,9 +314,13 @@ break; case EIO_READ: - SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0)); - *SvEND (req->sv2) = 0; - PUSHs (sv_2mortal (newSViv (req->result))); + { + SvCUR_set (req->sv2, req->stroffset + (req->result > 0 ? req->result : 0)); + *SvEND (req->sv2) = 0; + SvPOK_only (req->sv2); + SvSETMAGIC (req->sv2); + PUSHs (sv_2mortal (newSViv (req->result))); + } break; case EIO_DUP2: @@ -503,7 +505,18 @@ \ if (GIMME_V != G_VOID) \ XPUSHs (req_sv (req, AIO_REQ_KLASS)); - + +static int +extract_fd (SV *fh, int wr) +{ + int fd = PerlIO_fileno (wr ? IoOFP (sv_2io (fh)) : IoIFP (sv_2io (fh))); + + if (fd < 0) + croak ("illegal fh argument, either not an OS file or read/write mode mismatch"); + + return fd; +} + MODULE = IO::AIO PACKAGE = IO::AIO PROTOTYPES: ENABLE @@ -520,6 +533,10 @@ #ifndef _WIN32 newCONSTSUB (stash, "S_IFIFO", newSViv (S_IFIFO)); #endif + newCONSTSUB (stash, "S_IFIFO", newSViv (S_IFIFO)); + newCONSTSUB (stash, "SYNC_FILE_RANGE_WAIT_BEFORE", newSViv (EIO_SYNC_FILE_RANGE_WAIT_BEFORE)); + newCONSTSUB (stash, "SYNC_FILE_RANGE_WRITE" , newSViv (EIO_SYNC_FILE_RANGE_WRITE)); + newCONSTSUB (stash, "SYNC_FILE_RANGE_WAIT_AFTER" , newSViv (EIO_SYNC_FILE_RANGE_WAIT_AFTER)); create_respipe (); @@ -590,11 +607,30 @@ aio_fdatasync = EIO_FDATASYNC PPCODE: { + int fd = extract_fd (fh, 0); dREQ; req->type = ix; req->sv1 = newSVsv (fh); - req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); + req->int1 = fd; + + REQ_SEND (req); +} + +void +aio_sync_file_range (SV *fh, SV *offset, SV *nbytes, IV flags, SV *callback=&PL_sv_undef) + PROTOTYPE: $$$$;$ + PPCODE: +{ + int fd = extract_fd (fh, 0); + dREQ; + + req->type = EIO_SYNC_FILE_RANGE; + req->sv1 = newSVsv (fh); + req->int1 = fd; + req->offs = SvVAL64 (offset); + req->size = SvVAL64 (nbytes); + req->int2 = flags; REQ_SEND (req); } @@ -605,6 +641,7 @@ PPCODE: { static int close_pipe = -1; /* dummy fd to close fds via dup2 */ + int fd = extract_fd (fh, 0); dREQ; if (close_pipe < 0) @@ -622,7 +659,7 @@ req->type = EIO_DUP2; req->int1 = close_pipe; req->sv2 = newSVsv (fh); - req->int2 = PerlIO_fileno (IoIFP (sv_2io (fh))); + req->int2 = fd; REQ_SEND (req); } @@ -636,12 +673,10 @@ PPCODE: { STRLEN svlen; + int fd = extract_fd (fh, ix == EIO_WRITE); char *svptr = SvPVbyte (data, svlen); UV len = SvUV (length); - SvUPGRADE (data, SVt_PV); - SvPOK_on (data); - if (dataoffset < 0) dataoffset += svlen; @@ -656,7 +691,8 @@ } else { - /* read: grow scalar as necessary */ + /* read: check type and grow scalar as necessary */ + SvUPGRADE (data, SVt_PV); svptr = SvGROW (data, len + dataoffset + 1); } @@ -668,8 +704,7 @@ req->type = ix; req->sv1 = newSVsv (fh); - req->int1 = PerlIO_fileno (ix == EIO_READ ? IoIFP (sv_2io (fh)) - : IoOFP (sv_2io (fh))); + req->int1 = fd; req->offs = SvOK (offset) ? SvVAL64 (offset) : -1; req->size = len; req->sv2 = SvREFCNT_inc (data); @@ -706,13 +741,15 @@ PROTOTYPE: $$$$;$ PPCODE: { + int ifd = extract_fd (in_fh , 0); + int ofd = extract_fd (out_fh, 0); dREQ; req->type = EIO_SENDFILE; req->sv1 = newSVsv (out_fh); - req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh))); + req->int1 = ofd; req->sv2 = newSVsv (in_fh); - req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh))); + req->int2 = ifd; req->offs = SvVAL64 (in_offset); req->size = length; @@ -724,11 +761,12 @@ PROTOTYPE: $$$;$ PPCODE: { + int fd = extract_fd (fh, 0); dREQ; req->type = EIO_READAHEAD; req->sv1 = newSVsv (fh); - req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); + req->int1 = fd; req->offs = SvVAL64 (offset); req->size = length; @@ -1135,7 +1173,8 @@ CODE: { SvREFCNT_dec (grp->sv2); - grp->sv2 = newSVsv (callback); + grp->sv2 = newSVsv (callback); + grp->feed = aio_grp_feed; if (grp->int2 <= 0) grp->int2 = 2;