--- IO-AIO/AIO.xs 2005/08/23 12:37:19 1.37 +++ IO-AIO/AIO.xs 2006/07/21 07:35:31 1.42 @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,11 @@ # endif #endif +/* used for struct dirent, AIX doesn't provide it */ +#ifndef NAME_MAX +# define NAME_MAX 4096 +#endif + #if __ia64 # define STACKSIZE 65536 #else @@ -46,9 +52,9 @@ REQ_SENDFILE, REQ_STAT, REQ_LSTAT, REQ_FSTAT, REQ_FSYNC, REQ_FDATASYNC, - REQ_UNLINK, REQ_RMDIR, + REQ_UNLINK, REQ_RMDIR, REQ_RENAME, REQ_READDIR, - REQ_SYMLINK, + REQ_LINK, REQ_SYMLINK, }; typedef struct aio_cb { @@ -501,10 +507,10 @@ res = sbytes; } -# else +# endif +#else res = -1; errno = ENOSYS; -# endif #endif if (res < 0 @@ -519,11 +525,11 @@ char buf[4096]; res = 0; - for (;;) + while (count) { ssize_t cnt; - cnt = pread (ifd, buf, 4096, offset); + cnt = pread (ifd, buf, count > 4096 ? 4096 : count, offset); if (cnt <= 0) { @@ -541,6 +547,7 @@ offset += cnt; res += cnt; + count -= cnt; } } @@ -661,6 +668,8 @@ case REQ_CLOSE: req->result = close (req->fd); break; case REQ_UNLINK: req->result = unlink (req->dataptr); break; case REQ_RMDIR: req->result = rmdir (req->dataptr); break; + case REQ_RENAME: req->result = rename (req->data2ptr, req->dataptr); break; + case REQ_LINK: req->result = link (req->data2ptr, req->dataptr); break; case REQ_SYMLINK: req->result = symlink (req->data2ptr, req->dataptr); break; case REQ_FDATASYNC: req->result = fdatasync (req->fd); break; @@ -776,22 +785,27 @@ BOOT: { + HV *stash = gv_stashpv ("IO::AIO", 1); + newCONSTSUB (stash, "EXDEV", newSViv (EXDEV)); + newCONSTSUB (stash, "O_RDONLY", newSViv (O_RDONLY)); + newCONSTSUB (stash, "O_WRONLY", newSViv (O_WRONLY)); + create_pipe (); pthread_atfork (atfork_prepare, atfork_parent, atfork_child); } void -min_parallel(nthreads) +min_parallel (nthreads) int nthreads PROTOTYPE: $ void -max_parallel(nthreads) +max_parallel (nthreads) int nthreads PROTOTYPE: $ int -max_outstanding(nreqs) +max_outstanding (nreqs) int nreqs PROTOTYPE: $ CODE: @@ -799,7 +813,7 @@ max_outstanding = nreqs; void -aio_open(pathname,flags,mode,callback=&PL_sv_undef) +aio_open (pathname,flags,mode,callback=&PL_sv_undef) SV * pathname int flags int mode @@ -819,7 +833,7 @@ } void -aio_close(fh,callback=&PL_sv_undef) +aio_close (fh,callback=&PL_sv_undef) SV * fh SV * callback PROTOTYPE: $;$ @@ -839,7 +853,7 @@ } void -aio_read(fh,offset,length,data,dataoffset,callback=&PL_sv_undef) +aio_read (fh,offset,length,data,dataoffset,callback=&PL_sv_undef) SV * fh UV offset UV length @@ -903,7 +917,7 @@ } void -aio_sendfile(out_fh,in_fh,in_offset,length,callback=&PL_sv_undef) +aio_sendfile (out_fh,in_fh,in_offset,length,callback=&PL_sv_undef) SV * out_fh SV * in_fh UV in_offset @@ -926,7 +940,7 @@ } void -aio_readahead(fh,offset,length,callback=&PL_sv_undef) +aio_readahead (fh,offset,length,callback=&PL_sv_undef) SV * fh UV offset IV length @@ -946,7 +960,7 @@ } void -aio_stat(fh_or_path,callback=&PL_sv_undef) +aio_stat (fh_or_path,callback=&PL_sv_undef) SV * fh_or_path SV * callback ALIAS: @@ -980,12 +994,13 @@ } void -aio_unlink(pathname,callback=&PL_sv_undef) +aio_unlink (pathname,callback=&PL_sv_undef) SV * pathname SV * callback ALIAS: - aio_unlink = REQ_UNLINK - aio_rmdir = REQ_RMDIR + aio_unlink = REQ_UNLINK + aio_rmdir = REQ_RMDIR + aio_readdir = REQ_READDIR CODE: { dREQ; @@ -998,15 +1013,19 @@ } void -aio_symlink(oldpath,newpath,callback=&PL_sv_undef) +aio_link (oldpath,newpath,callback=&PL_sv_undef) SV * oldpath SV * newpath SV * callback + ALIAS: + aio_link = REQ_LINK + aio_symlink = REQ_SYMLINK + aio_rename = REQ_RENAME CODE: { dREQ; - req->type = REQ_SYMLINK; + req->type = ix; req->fh = newSVsv (oldpath); req->data2ptr = SvPVbyte_nolen (req->fh); req->data = newSVsv (newpath); @@ -1015,23 +1034,31 @@ send_req (req); } +#if 0 + +# undocumented, because it does not cancel active requests void -aio_readdir(pathname,callback=&PL_sv_undef) - SV * pathname - SV * callback - CODE: +cancel_most_requests () + PROTOTYPE: + CODE: { - dREQ; - - req->type = REQ_READDIR; - req->data = newSVsv (pathname); - req->dataptr = SvPVbyte_nolen (req->data); - - send_req (req); + aio_req *req; + + pthread_mutex_lock (&reqlock); + for (req = reqs; req; req = req->next) + req->flags |= 1; + pthread_mutex_unlock (&reqlock); + + pthread_mutex_lock (&reslock); + for (req = ress; req; req = req->next) + req->flags |= 1; + pthread_mutex_unlock (&reslock); } +#endif + void -flush() +flush () PROTOTYPE: CODE: while (nreqs)