--- IO-AIO/AIO.xs 2007/06/01 06:00:40 1.100 +++ IO-AIO/AIO.xs 2007/06/03 09:44:17 1.102 @@ -48,6 +48,13 @@ /* buffer size for various temporary buffers */ #define AIO_BUFSIZE 65536 +/* use NV for 32 bit perls as it allows larger offsets */ +#if IVSIZE >= 8 +# define SvVAL64 SvIV +#else +# define SvVAL64 SvNV +#endif + #define dBUF \ char *aio_buf; \ LOCK (wrklock); \ @@ -61,12 +68,12 @@ enum { REQ_QUIT, REQ_OPEN, REQ_CLOSE, - REQ_READ, REQ_WRITE, REQ_READAHEAD, - REQ_SENDFILE, + REQ_READ, REQ_WRITE, + REQ_READAHEAD, REQ_SENDFILE, REQ_STAT, REQ_LSTAT, REQ_FSTAT, - REQ_UTIME, REQ_FUTIME, /* must be consecutive */ - REQ_CHMOD, REQ_FCHMOD, /* must be consecutive */ - REQ_CHOWN, REQ_FCHOWN, /* must be consecutive */ + REQ_UTIME, REQ_FUTIME, + REQ_CHMOD, REQ_FCHMOD, + REQ_CHOWN, REQ_FCHOWN, REQ_FSYNC, REQ_FDATASYNC, REQ_UNLINK, REQ_RMDIR, REQ_MKDIR, REQ_RENAME, REQ_MKNOD, REQ_READDIR, @@ -319,7 +326,7 @@ static int poll_cb (); static int req_invoke (aio_req req); -static void req_free (aio_req req); +static void req_destroy (aio_req req); static void req_cancel (aio_req req); /* must be called at most once */ @@ -395,12 +402,12 @@ if (!req_invoke (grp)) { - req_free (grp); + req_destroy (grp); unblock_sig (); croak (0); } - req_free (grp); + req_destroy (grp); unblock_sig (); } } @@ -538,7 +545,7 @@ return !SvTRUE (ERRSV); } -static void req_free (aio_req req) +static void req_destroy (aio_req req) { if (req->self) { @@ -577,7 +584,7 @@ req_cancel_subs (req); } -static void *aio_proc(void *arg); +static void *aio_proc (void *arg); static void start_thread (void) { @@ -747,7 +754,7 @@ { if (!req_invoke (req)) { - req_free (req); + req_destroy (req); unblock_sig (); croak (0); } @@ -755,7 +762,7 @@ count++; } - req_free (req); + req_destroy (req); if (maxreqs && !--maxreqs) break; @@ -1133,8 +1140,12 @@ if (!(req->flags & FLAG_CANCELLED)) switch (req->type) { - case REQ_READ: req->result = pread (req->int1, req->ptr1, req->size, req->offs); break; - case REQ_WRITE: req->result = pwrite (req->int1, req->ptr1, req->size, req->offs); break; + case REQ_READ: req->result = req->offs >= 0 + ? pread (req->int1, req->ptr1, req->size, req->offs) + : read (req->int1, req->ptr1, req->size); break; + case REQ_WRITE: req->result = req->offs >= 0 + ? pwrite (req->int1, req->ptr1, req->size, req->offs) + : write (req->int1, req->ptr1, req->size); break; case REQ_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; case REQ_SENDFILE: req->result = sendfile_ (req->int1, req->int2, req->offs, req->size, self); break; @@ -1272,17 +1283,17 @@ aio_req prv; while (prv = reqq_shift (&req_queue)) - req_free (prv); + req_destroy (prv); while (prv = reqq_shift (&res_queue)) - req_free (prv); + req_destroy (prv); while (wrk_first.next != &wrk_first) { worker *wrk = wrk_first.next; if (wrk->req) - req_free (wrk->req); + req_destroy (wrk->req); worker_clear (wrk); worker_free (wrk); @@ -1412,7 +1423,7 @@ } void -aio_read (SV *fh, UV offset, UV length, SV8 *data, UV dataoffset, SV *callback=&PL_sv_undef) +aio_read (SV *fh, SV *offset, SV *length, SV8 *data, IV dataoffset, SV *callback=&PL_sv_undef) ALIAS: aio_read = REQ_READ aio_write = REQ_WRITE @@ -1421,6 +1432,7 @@ { STRLEN svlen; char *svptr = SvPVbyte (data, svlen); + UV len = SvUV (length); SvUPGRADE (data, SVt_PV); SvPOK_on (data); @@ -1429,21 +1441,21 @@ dataoffset += svlen; if (dataoffset < 0 || dataoffset > svlen) - croak ("data offset outside of string"); + croak ("dataoffset outside of data scalar"); if (ix == REQ_WRITE) { /* write: check length and adjust. */ - if (length < 0 || length + dataoffset > svlen) - length = svlen - dataoffset; + if (!SvOK (length) || len + dataoffset > svlen) + len = svlen - dataoffset; } else { /* read: grow scalar as necessary */ - svptr = SvGROW (data, length + dataoffset + 1); + svptr = SvGROW (data, len + dataoffset + 1); } - if (length < 0) + if (len < 0) croak ("length must not be negative"); { @@ -1453,8 +1465,8 @@ req->sv1 = newSVsv (fh); req->int1 = PerlIO_fileno (ix == REQ_READ ? IoIFP (sv_2io (fh)) : IoOFP (sv_2io (fh))); - req->offs = offset; - req->size = length; + req->offs = SvOK (offset) ? SvVAL64 (offset) : -1; + req->size = len; req->sv2 = SvREFCNT_inc (data); req->ptr1 = (char *)svptr + dataoffset; req->stroffset = dataoffset; @@ -1490,7 +1502,7 @@ } void -aio_sendfile (SV *out_fh, SV *in_fh, UV in_offset, UV length, SV *callback=&PL_sv_undef) +aio_sendfile (SV *out_fh, SV *in_fh, SV *in_offset, UV length, SV *callback=&PL_sv_undef) PROTOTYPE: $$$$;$ PPCODE: { @@ -1501,14 +1513,14 @@ req->int1 = PerlIO_fileno (IoIFP (sv_2io (out_fh))); req->sv2 = newSVsv (in_fh); req->int2 = PerlIO_fileno (IoIFP (sv_2io (in_fh))); - req->offs = in_offset; + req->offs = SvVAL64 (in_offset); req->size = length; REQ_SEND; } void -aio_readahead (SV *fh, UV offset, IV length, SV *callback=&PL_sv_undef) +aio_readahead (SV *fh, SV *offset, IV length, SV *callback=&PL_sv_undef) PROTOTYPE: $$$;$ PPCODE: { @@ -1517,7 +1529,7 @@ req->type = REQ_READAHEAD; req->sv1 = newSVsv (fh); req->int1 = PerlIO_fileno (IoIFP (sv_2io (fh))); - req->offs = offset; + req->offs = SvVAL64 (offset); req->size = length; REQ_SEND; @@ -1535,7 +1547,7 @@ req->ptr2 = malloc (sizeof (Stat_t)); if (!req->ptr2) { - req_free (req); + req_destroy (req); croak ("out of memory during aio_stat statdata allocation"); }