--- IO-AIO/AIO.xs 2006/10/30 23:30:00 1.86 +++ IO-AIO/AIO.xs 2006/10/31 00:32:19 1.90 @@ -89,6 +89,8 @@ if (!aio_buf) \ return -1; +typedef SV SV8; /* byte-sv, used for argument-checking */ + enum { REQ_QUIT, REQ_OPEN, REQ_CLOSE, @@ -113,7 +115,6 @@ SV *callback, *fh; SV *sv1, *sv2; void *ptr1, *ptr2; - Stat_t *statdata; off_t offs; size_t size; ssize_t result; @@ -132,8 +133,9 @@ } aio_cb; enum { - FLAG_CANCELLED = 0x01, - FLAG_DATA_RO_OFF = 0x80, /* data was set readonly */ + FLAG_CANCELLED = 0x01, /* request was cancelled */ + FLAG_SV1_RO_OFF = 0x40, /* data was set readonly */ + FLAG_PTR2_FREE = 0x80, /* need to free(ptr2) */ }; typedef aio_cb *aio_req; @@ -398,16 +400,9 @@ { dSP; - if (req->flags & FLAG_DATA_RO_OFF) + if (req->flags & FLAG_SV1_RO_OFF) SvREADONLY_off (req->sv1); - if (req->statdata) - { - PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT; - PL_laststatval = req->result; - PL_statcache = *(req->statdata); - } - if (!(req->flags & FLAG_CANCELLED) && SvOK (req->callback)) { ENTER; @@ -488,10 +483,21 @@ } break; + case REQ_STAT: + case REQ_LSTAT: + case REQ_FSTAT: + PL_laststype = req->type == REQ_LSTAT ? OP_LSTAT : OP_STAT; + PL_laststatval = req->result; + PL_statcache = *(Stat_t *)(req->ptr2); + PUSHs (sv_2mortal (newSViv (req->result))); + break; + case REQ_READ: SvCUR_set (req->sv1, req->stroffset + (req->result > 0 ? req->result : 0)); *SvEND (req->sv1) = 0; - /* fall through */ + PUSHs (sv_2mortal (newSViv (req->result))); + break; + default: PUSHs (sv_2mortal (newSViv (req->result))); break; @@ -540,9 +546,8 @@ SvREFCNT_dec (req->sv1); SvREFCNT_dec (req->sv2); SvREFCNT_dec (req->callback); - Safefree (req->statdata); - if (req->type == REQ_READDIR) + if (req->flags & FLAG_PTR2_FREE) free (req->ptr2); Safefree (req); @@ -999,6 +1004,7 @@ LOCK (wrklock); self->dirp = dirp = opendir (req->ptr1); self->dbuf = u = malloc (sizeof (*u)); + req->flags |= FLAG_PTR2_FREE; req->ptr2 = names = malloc (memlen); UNLOCK (wrklock); @@ -1104,9 +1110,9 @@ 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; - case REQ_STAT: req->result = stat (req->ptr1, req->statdata); break; - case REQ_LSTAT: req->result = lstat (req->ptr1, req->statdata); break; - case REQ_FSTAT: req->result = fstat (req->int1, req->statdata); break; + case REQ_STAT: req->result = stat (req->ptr1, (Stat_t *)req->ptr2); break; + case REQ_LSTAT: req->result = lstat (req->ptr1, (Stat_t *)req->ptr2); break; + case REQ_FSTAT: req->result = fstat (req->int1, (Stat_t *)req->ptr2); break; case REQ_OPEN: req->result = open (req->ptr1, req->int1, req->mode); break; case REQ_CLOSE: req->result = close (req->int1); break; @@ -1307,7 +1313,7 @@ void aio_open (pathname,flags,mode,callback=&PL_sv_undef) - SV * pathname + SV8 * pathname int flags int mode SV * callback @@ -1318,7 +1324,7 @@ req->type = REQ_OPEN; req->sv1 = newSVsv (pathname); - req->ptr1 = SvPVbyte_nolen (pathname); + req->ptr1 = SvPVbyte_nolen (req->sv1); req->int1 = flags; req->mode = mode; @@ -1350,7 +1356,7 @@ SV * fh UV offset UV length - SV * data + SV8 * data UV dataoffset SV * callback ALIAS: @@ -1402,7 +1408,7 @@ if (!SvREADONLY (data)) { SvREADONLY_on (data); - req->flags |= FLAG_DATA_RO_OFF; + req->flags |= FLAG_SV1_RO_OFF; } REQ_SEND; @@ -1411,7 +1417,7 @@ void aio_readlink (path,callback=&PL_sv_undef) - SV * path + SV8 * path SV * callback PROTOTYPE: $$;$ PPCODE: @@ -1424,7 +1430,7 @@ req->type = REQ_READLINK; req->fh = newSVsv (path); - req->ptr2 = SvPVbyte_nolen (path); + req->ptr2 = SvPVbyte_nolen (req->fh); req->sv1 = data; req->ptr1 = SvPVbyte_nolen (data); @@ -1476,7 +1482,7 @@ void aio_stat (fh_or_path,callback=&PL_sv_undef) - SV * fh_or_path + SV8 * fh_or_path SV * callback ALIAS: aio_stat = REQ_STAT @@ -1485,18 +1491,20 @@ { dREQ; - New (0, req->statdata, 1, Stat_t); - if (!req->statdata) + req->ptr2 = malloc (sizeof (Stat_t)); + if (!req->ptr2) { req_free (req); - croak ("out of memory during aio_req->statdata allocation"); + croak ("out of memory during aio_stat statdata allocation"); } + req->flags |= FLAG_PTR2_FREE; + if (SvPOK (fh_or_path)) { req->type = ix; req->sv1 = newSVsv (fh_or_path); - req->ptr1 = SvPVbyte_nolen (fh_or_path); + req->ptr1 = SvPVbyte_nolen (req->sv1); } else { @@ -1510,7 +1518,7 @@ void aio_unlink (pathname,callback=&PL_sv_undef) - SV * pathname + SV8 * pathname SV * callback ALIAS: aio_unlink = REQ_UNLINK @@ -1522,15 +1530,15 @@ req->type = ix; req->sv1 = newSVsv (pathname); - req->ptr1 = SvPVbyte_nolen (pathname); - + req->ptr1 = SvPVbyte_nolen (req->sv1); + REQ_SEND; } void aio_link (oldpath,newpath,callback=&PL_sv_undef) - SV * oldpath - SV * newpath + SV8 * oldpath + SV8 * newpath SV * callback ALIAS: aio_link = REQ_LINK @@ -1544,14 +1552,14 @@ req->fh = newSVsv (oldpath); req->ptr2 = SvPVbyte_nolen (req->fh); req->sv1 = newSVsv (newpath); - req->ptr1 = SvPVbyte_nolen (newpath); + req->ptr1 = SvPVbyte_nolen (req->sv1); REQ_SEND; } void aio_mknod (pathname,mode,dev,callback=&PL_sv_undef) - SV * pathname + SV8 * pathname SV * callback UV mode UV dev @@ -1561,7 +1569,7 @@ req->type = REQ_MKNOD; req->sv1 = newSVsv (pathname); - req->ptr1 = SvPVbyte_nolen (pathname); + req->ptr1 = SvPVbyte_nolen (req->sv1); req->mode = (mode_t)mode; req->offs = dev;