--- IO-AIO/README 2014/01/25 00:15:52 1.55 +++ IO-AIO/README 2024/02/16 21:20:52 1.71 @@ -1,5 +1,5 @@ NAME - IO::AIO - Asynchronous Input/Output + IO::AIO - Asynchronous/Advanced Input/Output SYNOPSIS use IO::AIO; @@ -57,6 +57,10 @@ aio_write, so the remaining functionality would have to be implemented using threads anyway. + In addition to asynchronous I/O, this module also exports some rather + arcane interfaces, such as "madvise" or linux's "splice" system call, + which is why the "A" in "AIO" can also mean *advanced*. + Although the module will work in the presence of other (Perl-) threads, it is currently not reentrant in any way, so use appropriate locking yourself, always call "poll_cb" from within the same thread, or never @@ -92,7 +96,7 @@ print $contents; # exit event loop and program - EV::unloop; + EV::break; }; }; @@ -100,7 +104,7 @@ # check for sockets etc. etc. # process events as long as there are some: - EV::loop; + EV::run; REQUEST ANATOMY AND LIFETIME Every "aio_*" function creates a request. which is a C data structure @@ -173,8 +177,9 @@ aio_link $srcpath, $dstpath, $callback->($status) aio_symlink $srcpath, $dstpath, $callback->($status) aio_readlink $pathname, $callback->($link) - aio_realpath $pathname, $callback->($link) + aio_realpath $pathname, $callback->($path) aio_rename $srcpath, $dstpath, $callback->($status) + aio_rename2 $srcpath, $dstpath, $flags, $callback->($status) aio_mkdir $pathname, $mode, $callback->($status) aio_rmdir $pathname, $callback->($status) aio_readdir $pathname, $callback->($entries) @@ -186,13 +191,15 @@ aio_copy $srcpath, $dstpath, $callback->($status) aio_move $srcpath, $dstpath, $callback->($status) aio_rmtree $pathname, $callback->($status) + aio_fcntl $fh, $cmd, $arg, $callback->($status) + aio_ioctl $fh, $request, $buf, $callback->($status) aio_sync $callback->($status) aio_syncfs $fh, $callback->($status) aio_fsync $fh, $callback->($status) aio_fdatasync $fh, $callback->($status) aio_sync_file_range $fh, $offset, $nbytes, $flags, $callback->($status) aio_pathsync $pathname, $callback->($status) - aio_msync $scalar, $offset = 0, $length = undef, flags = 0, $callback->($status) + aio_msync $scalar, $offset = 0, $length = undef, flags = MS_SYNC, $callback->($status) aio_mtouch $scalar, $offset = 0, $length = undef, flags = 0, $callback->($status) aio_mlock $scalar, $offset = 0, $length = undef, $callback->($status) aio_mlockall $flags, $callback->($status) @@ -216,16 +223,53 @@ IO::AIO::nreqs IO::AIO::nready IO::AIO::npending + IO::AIO::reinit + + $nfd = IO::AIO::get_fdlimit + IO::AIO::min_fdlimit $nfd IO::AIO::sendfile $ofh, $ifh, $offset, $count IO::AIO::fadvise $fh, $offset, $len, $advice + IO::AIO::fexecve $fh, $argv, $envp + IO::AIO::mmap $scalar, $length, $prot, $flags[, $fh[, $offset]] IO::AIO::munmap $scalar + IO::AIO::mremap $scalar, $new_length, $flags[, $new_address] IO::AIO::madvise $scalar, $offset, $length, $advice IO::AIO::mprotect $scalar, $offset, $length, $protect IO::AIO::munlock $scalar, $offset = 0, $length = undef IO::AIO::munlockall + # stat extensions + $counter = IO::AIO::st_gen + $seconds = IO::AIO::st_atime, IO::AIO::st_mtime, IO::AIO::st_ctime, IO::AIO::st_btime + ($atime, $mtime, $ctime, $btime, ...) = IO::AIO::st_xtime + $nanoseconds = IO::AIO::st_atimensec, IO::AIO::st_mtimensec, IO::AIO::st_ctimensec, IO::AIO::st_btimensec + $seconds = IO::AIO::st_btimesec + ($atime, $mtime, $ctime, $btime, ...) = IO::AIO::st_xtimensec + + # very much unportable syscalls + IO::AIO::accept4 $r_fh, $sockaddr, $sockaddr_len, $flags + IO::AIO::splice $r_fh, $r_off, $w_fh, $w_off, $length, $flags + IO::AIO::tee $r_fh, $w_fh, $length, $flags + + $actual_size = IO::AIO::pipesize $r_fh[, $new_size] + ($rfh, $wfh) = IO::AIO::pipe2 [$flags] + + $fh = IO::AIO::eventfd [$initval, [$flags]] + $fh = IO::AIO::memfd_create $pathname[, $flags] + + $fh = IO::AIO::timerfd_create $clockid[, $flags] + ($cur_interval, $cur_value) = IO::AIO::timerfd_settime $fh, $flags, $new_interval, $nbw_value + ($cur_interval, $cur_value) = IO::AIO::timerfd_gettime $fh + + $fh = IO::AIO::pidfd_open $pid[, $flags] + $status = IO::AIO::pidfd_send_signal $pidfh, $signal[, $siginfo[, $flags]] + $fh = IO::AIO::pidfd_getfd $pidfh, $targetfd[, $flags] + + $retval = IO::AIO::mount $special, $path, $fstype, $flags = 0, $data = undef + $retval = IO::AIO::umount $path, $flags = 0 + API NOTES All the "aio_*" calls are more or less thin wrappers around the syscall with the same name (sans "aio_"). The arguments are similar or @@ -301,9 +345,6 @@ newly created filehandle for the file (or "undef" in case of an error). - The pathname passed to "aio_open" must be absolute. See API NOTES, - above, for an explanation. - The $flags argument is a bitmask. See the "Fcntl" module for a list. They are the same as used by "sysopen". @@ -332,7 +373,8 @@ "O_ASYNC", "O_DIRECT", "O_NOATIME", "O_CLOEXEC", "O_NOCTTY", "O_NOFOLLOW", "O_NONBLOCK", "O_EXEC", "O_SEARCH", "O_DIRECTORY", - "O_DSYNC", "O_RSYNC", "O_SYNC" and "O_TTY_INIT". + "O_DSYNC", "O_RSYNC", "O_SYNC", "O_PATH", "O_TMPFILE", "O_TTY_INIT" + and "O_ACCMODE". aio_close $fh, $callback->($status) Asynchronously close a file and call the callback with the result @@ -372,8 +414,8 @@ aio_write $fh,$offset,$length, $data,$dataoffset, $callback->($retval) Reads or writes $length bytes from or to the specified $fh and $offset into the scalar given by $data and offset $dataoffset and - calls the callback without the actual number of bytes read (or -1 on - error, just like the syscall). + calls the callback with the actual number of bytes transferred (or + -1 on error, just like the syscall). "aio_read" will, like "sysread", shrink or grow the $data scalar to offset plus the actual number of bytes read. @@ -440,7 +482,7 @@ rather buggy on many systems, this implementation tries to work around some known bugs in Linux and FreeBSD kernels (probably others, too), but that might fail, so you really really should check - the return value of "aio_sendfile" - fewre bytes than expected might + the return value of "aio_sendfile" - fewer bytes than expected might have been transferred. aio_readahead $fh,$offset,$length, $callback->($retval) @@ -454,18 +496,16 @@ read beyond the end of the file. The current file offset of the file is left unchanged. - If that syscall doesn't exist (likely if your OS isn't Linux) it + If that syscall doesn't exist (likely if your kernel isn't Linux) it will be emulated by simply reading the data, which would have a similar effect. aio_stat $fh_or_path, $callback->($status) aio_lstat $fh, $callback->($status) - Works like perl's "stat" or "lstat" in void context. The callback - will be called after the stat and the results will be available - using "stat _" or "-s _" etc... - - The pathname passed to "aio_stat" must be absolute. See API NOTES, - above, for an explanation. + Works almost exactly like perl's "stat" or "lstat" in void context. + The callback will be called after the stat and the results will be + available using "stat _" or "-s _" and other tests (with the + exception of "-B" and "-T"). Currently, the stats are always 64-bit-stats, i.e. instead of returning an error when stat'ing a large file, the results will be @@ -481,6 +521,9 @@ "S_IFDIR", "S_IFWHT", "S_IFSOCK", "IO::AIO::major $dev_t", "IO::AIO::minor $dev_t", "IO::AIO::makedev $major, $minor". + To access higher resolution stat timestamps, see "SUBSECOND STAT + TIME ACCESS". + Example: Print the length of /etc/passwd: aio_stat "/etc/passwd", sub { @@ -531,96 +574,15 @@ fsid => 1810 } - Here is a (likely partial - send me updates!) list of fsid values - used by Linux - it is safe to hardcode these when $^O is "linux": - - 0x0000adf5 adfs - 0x0000adff affs - 0x5346414f afs - 0x09041934 anon-inode filesystem - 0x00000187 autofs - 0x42465331 befs - 0x1badface bfs - 0x42494e4d binfmt_misc - 0x9123683e btrfs - 0x0027e0eb cgroupfs - 0xff534d42 cifs - 0x73757245 coda - 0x012ff7b7 coh - 0x28cd3d45 cramfs - 0x453dcd28 cramfs-wend (wrong endianness) - 0x64626720 debugfs - 0x00001373 devfs - 0x00001cd1 devpts - 0x0000f15f ecryptfs - 0x00414a53 efs - 0x0000137d ext - 0x0000ef53 ext2/ext3 - 0x0000ef51 ext2 - 0x00004006 fat - 0x65735546 fuseblk - 0x65735543 fusectl - 0x0bad1dea futexfs - 0x01161970 gfs2 - 0x47504653 gpfs - 0x00004244 hfs - 0xf995e849 hpfs - 0x958458f6 hugetlbfs - 0x2bad1dea inotifyfs - 0x00009660 isofs - 0x000072b6 jffs2 - 0x3153464a jfs - 0x6b414653 k-afs - 0x0bd00bd0 lustre - 0x0000137f minix - 0x0000138f minix 30 char names - 0x00002468 minix v2 - 0x00002478 minix v2 30 char names - 0x00004d5a minix v3 - 0x19800202 mqueue - 0x00004d44 msdos - 0x0000564c novell - 0x00006969 nfs - 0x6e667364 nfsd - 0x00003434 nilfs - 0x5346544e ntfs - 0x00009fa1 openprom - 0x7461636F ocfs2 - 0x00009fa0 proc - 0x6165676c pstorefs - 0x0000002f qnx4 - 0x858458f6 ramfs - 0x52654973 reiserfs - 0x00007275 romfs - 0x67596969 rpc_pipefs - 0x73636673 securityfs - 0xf97cff8c selinux - 0x0000517b smb - 0x534f434b sockfs - 0x73717368 squashfs - 0x62656572 sysfs - 0x012ff7b6 sysv2 - 0x012ff7b5 sysv4 - 0x01021994 tmpfs - 0x15013346 udf - 0x00011954 ufs - 0x54190100 ufs byteswapped - 0x00009fa2 usbdevfs - 0x01021997 v9fs - 0xa501fcf5 vxfs - 0xabba1974 xenfs - 0x012ff7b4 xenix - 0x58465342 xfs - 0x012fd16d xia - aio_utime $fh_or_path, $atime, $mtime, $callback->($status) Works like perl's "utime" function (including the special case of $atime and $mtime being undef). Fractional times are supported if the underlying syscalls support them. - When called with a pathname, uses utimes(2) if available, otherwise - utime(2). If called on a file descriptor, uses futimes(2) if - available, otherwise returns ENOSYS, so this is not portable. + When called with a pathname, uses utimensat(2) or utimes(2) if + available, otherwise utime(2). If called on a file descriptor, uses + futimens(2) or futimes(2) if available, otherwise returns ENOSYS, so + this is not portable. Examples: @@ -645,15 +607,22 @@ Works like truncate(2) or ftruncate(2). aio_allocate $fh, $mode, $offset, $len, $callback->($status) - Allocates or freed disk space according to the $mode argument. See - the linux "fallocate" docuemntation for details. + Allocates or frees disk space according to the $mode argument. See + the linux "fallocate" documentation for details. - $mode can currently be 0 or "IO::AIO::FALLOC_FL_KEEP_SIZE" to - allocate space, or "IO::AIO::FALLOC_FL_PUNCH_HOLE | + $mode is usually 0 or "IO::AIO::FALLOC_FL_KEEP_SIZE" to allocate + space, or "IO::AIO::FALLOC_FL_PUNCH_HOLE | IO::AIO::FALLOC_FL_KEEP_SIZE", to deallocate a file range. + IO::AIO also supports "FALLOC_FL_COLLAPSE_RANGE", to remove a range + (without leaving a hole), "FALLOC_FL_ZERO_RANGE", to zero a range, + "FALLOC_FL_INSERT_RANGE" to insert a range and + "FALLOC_FL_UNSHARE_RANGE" to unshare shared blocks (see your + fallocate(2) manpage). + The file system block size used by "fallocate" is presumably the - "f_bsize" returned by "statvfs". + "f_bsize" returned by "statvfs", but different filesystems and + filetypes can dictate other limitations. If "fallocate" isn't available or cannot be emulated (currently no emulation will be attempted), passes -1 and sets $! to "ENOSYS". @@ -707,6 +676,21 @@ natively, the case "[$wd, "."]" as $srcpath is specialcased - instead of failing, "rename" is called on the absolute path of $wd. + aio_rename2 $srcpath, $dstpath, $flags, $callback->($status) + Basically a version of "aio_rename" with an additional $flags + argument. Calling this with "$flags=0" is the same as calling + "aio_rename". + + Non-zero flags are currently only supported on GNU/Linux systems + that support renameat2. Other systems fail with "ENOSYS" in this + case. + + The following constants are available (missing ones are, as usual + 0), see renameat2(2) for details: + + "IO::AIO::RENAME_NOREPLACE", "IO::AIO::RENAME_EXCHANGE" and + "IO::AIO::RENAME_WHITEOUT". + aio_mkdir $pathname, $mode, $callback->($status) Asynchronously mkdir (create) a directory and call the callback with the result code. $mode will be modified by the umask at the time the @@ -738,10 +722,10 @@ modified): IO::AIO::READDIR_DENTS - When this flag is off, then the callback gets an arrayref - consisting of names only (as with "aio_readdir"), otherwise it + Normally the callback gets an arrayref consisting of names only + (as with "aio_readdir"). If this flag is set, then the callback gets an arrayref with "[$name, $type, $inode]" arrayrefs, each - describing a single directory entry in more detail. + describing a single directory entry in more detail: $name is the name of the entry. @@ -752,9 +736,9 @@ "IO::AIO::DT_LNK", "IO::AIO::DT_SOCK", "IO::AIO::DT_WHT". "IO::AIO::DT_UNKNOWN" means just that: readdir does not know. If - you need to know, you have to run stat yourself. Also, for speed - reasons, the $type scalars are read-only: you can not modify - them. + you need to know, you have to run stat yourself. Also, for + speed/memory reasons, the $type scalars are read-only: you must + not modify them. $inode is the inode number (which might not be exact on systems with 64 bit inode numbers and 32 bit perls). This field has @@ -776,12 +760,13 @@ IO::AIO::READDIR_STAT_ORDER When this flag is set, then the names will be returned in an order suitable for stat()'ing each one. That is, when you plan - to stat() all files in the given directory, then the returned - order will likely be fastest. + to stat() most or all files in the given directory, then the + returned order will likely be faster. If both this flag and "IO::AIO::READDIR_DIRS_FIRST" are specified, then the likely dirs come first, resulting in a less - optimal stat order. + optimal stat order for stat'ing all entries, but likely a more + optimal order for finding subdirectories. IO::AIO::READDIR_FOUND_UNKNOWN This flag should not be set when calling "aio_readdirx". @@ -790,15 +775,47 @@ flag therefore indicates that all $type's are known, which can be used to speed up some algorithms. + aio_slurp $pathname, $offset, $length, $data, $callback->($status) + Opens, reads and closes the given file. The data is put into $data, + which is resized as required. + + If $offset is negative, then it is counted from the end of the file. + + If $length is zero, then the remaining length of the file is used. + Also, in this case, the same limitations to modifying $data apply as + when IO::AIO::mmap is used, i.e. it must only be modified in-place + with "substr". If the size of the file is known, specifying a + non-zero $length results in a performance advantage. + + This request is similar to the older "aio_load" request, but since + it is a single request, it might be more efficient to use. + + Example: load /etc/passwd into $passwd. + + my $passwd; + aio_slurp "/etc/passwd", 0, 0, $passwd, sub { + $_[0] >= 0 + or die "/etc/passwd: $!\n"; + + printf "/etc/passwd is %d bytes long, and contains:\n", length $passwd; + print $passwd; + }; + IO::AIO::flush; + aio_load $pathname, $data, $callback->($status) This is a composite request that tries to fully load the given file into memory. Status is the same as with aio_read. + Using "aio_slurp" might be more efficient, as it is a single + request. + aio_copy $srcpath, $dstpath, $callback->($status) Try to copy the *file* (directories not supported as either source or destination) from $srcpath to $dstpath and call the callback with a status of 0 (ok) or -1 (error, see $!). + Existing destination files will be truncated. + This is a composite request that creates the destination file with mode 0200 and copies the contents of the source file into it using "aio_sendfile", followed by restoring atime, mtime, access mode and @@ -824,8 +841,8 @@ you cannot recurse into (everything else, including symlinks to directories). - "aio_scandir" is a composite request that creates of many sub - requests_ $maxreq specifies the maximum number of outstanding aio + "aio_scandir" is a composite request that generates many sub + requests. $maxreq specifies the maximum number of outstanding aio requests that this function generates. If it is "<= 0", then a suitable default will be chosen (currently 4). @@ -842,8 +859,7 @@ Implementation notes. - The "aio_readdir" cannot be avoided, but "stat()"'ing every entry - can. + The "aio_readdir" cannot be avoided, but stat()'ing every entry can. If readdir returns file type information, then this is used directly to find directories. @@ -882,6 +898,61 @@ uses "aio_scandir" to recurse into and rmdir directories, and unlink everything else. + aio_fcntl $fh, $cmd, $arg, $callback->($status) + aio_ioctl $fh, $request, $buf, $callback->($status) + These work just like the "fcntl" and "ioctl" built-in functions, + except they execute asynchronously and pass the return value to the + callback. + + Both calls can be used for a lot of things, some of which make more + sense to run asynchronously in their own thread, while some others + make less sense. For example, calls that block waiting for external + events, such as locking, will also lock down an I/O thread while it + is waiting, which can deadlock the whole I/O system. At the same + time, there might be no alternative to using a thread to wait. + + So in general, you should only use these calls for things that do + (filesystem) I/O, not for things that wait for other events + (network, other processes), although if you are careful and know + what you are doing, you still can. + + The following constants are available and can be used for normal + "ioctl" and "fcntl" as well (missing ones are, as usual 0): + + "F_DUPFD_CLOEXEC", + + "F_OFD_GETLK", "F_OFD_SETLK", "F_OFD_GETLKW", + + "FIFREEZE", "FITHAW", "FITRIM", "FICLONE", "FICLONERANGE", + "FIDEDUPERANGE". + + "F_ADD_SEALS", "F_GET_SEALS", "F_SEAL_SEAL", "F_SEAL_SHRINK", + "F_SEAL_GROW" and "F_SEAL_WRITE". + + "FS_IOC_GETFLAGS", "FS_IOC_SETFLAGS", "FS_IOC_GETVERSION", + "FS_IOC_SETVERSION", "FS_IOC_FIEMAP". + + "FS_IOC_FSGETXATTR", "FS_IOC_FSSETXATTR", + "FS_IOC_SET_ENCRYPTION_POLICY", "FS_IOC_GET_ENCRYPTION_PWSALT", + "FS_IOC_GET_ENCRYPTION_POLICY", "FS_KEY_DESCRIPTOR_SIZE". + + "FS_SECRM_FL", "FS_UNRM_FL", "FS_COMPR_FL", "FS_SYNC_FL", + "FS_IMMUTABLE_FL", "FS_APPEND_FL", "FS_NODUMP_FL", "FS_NOATIME_FL", + "FS_DIRTY_FL", "FS_COMPRBLK_FL", "FS_NOCOMP_FL", "FS_ENCRYPT_FL", + "FS_BTREE_FL", "FS_INDEX_FL", "FS_JOURNAL_DATA_FL", "FS_NOTAIL_FL", + "FS_DIRSYNC_FL", "FS_TOPDIR_FL", "FS_FL_USER_MODIFIABLE". + + "FS_XFLAG_REALTIME", "FS_XFLAG_PREALLOC", "FS_XFLAG_IMMUTABLE", + "FS_XFLAG_APPEND", "FS_XFLAG_SYNC", "FS_XFLAG_NOATIME", + "FS_XFLAG_NODUMP", "FS_XFLAG_RTINHERIT", "FS_XFLAG_PROJINHERIT", + "FS_XFLAG_NOSYMLINKS", "FS_XFLAG_EXTSIZE", "FS_XFLAG_EXTSZINHERIT", + "FS_XFLAG_NODEFRAG", "FS_XFLAG_FILESTREAM", "FS_XFLAG_DAX", + "FS_XFLAG_HASATTR", + + "BLKROSET", "BLKROGET", "BLKRRPART", "BLKGETSIZE", "BLKFLSBUF", + "BLKRASET", "BLKRAGET", "BLKFRASET", "BLKFRAGET", "BLKSECTSET", + "BLKSECTGET", "BLKSSZGET", "BLKBSZGET", "BLKBSZSET", "BLKGETSIZE64", + aio_sync $callback->($status) Asynchronously call sync and call the callback when finished. @@ -927,7 +998,7 @@ Passes 0 when everything went ok, and -1 on error. - aio_msync $scalar, $offset = 0, $length = undef, flags = 0, + aio_msync $scalar, $offset = 0, $length = undef, flags = MS_SYNC, $callback->($status) This is a rather advanced IO::AIO call, which only works on mmap(2)ed scalars (see the "IO::AIO::mmap" function, although it @@ -939,8 +1010,8 @@ memory area starting at $offset in the string and ending $length bytes later. If $length is negative, counts from the end, and if $length is "undef", then it goes till the end of the string. The - flags can be a combination of "IO::AIO::MS_ASYNC", - "IO::AIO::MS_INVALIDATE" and "IO::AIO::MS_SYNC". + flags can be either "IO::AIO::MS_ASYNC" or "IO::AIO::MS_SYNC", plus + an optional "IO::AIO::MS_INVALIDATE". aio_mtouch $scalar, $offset = 0, $length = undef, flags = 0, $callback->($status) @@ -981,10 +1052,13 @@ aio_mlockall $flags, $callback->($status) Calls the "mlockall" function with the given $flags (a combination - of "IO::AIO::MCL_CURRENT" and "IO::AIO::MCL_FUTURE"). + of "IO::AIO::MCL_CURRENT", "IO::AIO::MCL_FUTURE" and + "IO::AIO::MCL_ONFAULT"). On systems that do not implement "mlockall", this function returns - -1 and sets errno to "ENOSYS". + -1 and sets errno to "ENOSYS". Similarly, flag combinations not + supported by the system result in a return value of -1 with errno + being set to "EINVAL". Note that the corresponding "munlockall" is synchronous and is documented under "MISCELLANEOUS FUNCTIONS". @@ -1036,11 +1110,11 @@ "IO::AIO::FIEMAP_EXTENT_UNWRITTEN", "IO::AIO::FIEMAP_EXTENT_MERGED" or "IO::AIO::FIEMAP_EXTENT_SHARED". - At the time of this writing (Linux 3.2), this requets is unreliable + At the time of this writing (Linux 3.2), this request is unreliable unless $count is "undef", as the kernel has all sorts of bugs - preventing it to return all extents of a range for files with large - number of extents. The code works around all these issues if $count - is undef. + preventing it to return all extents of a range for files with a + large number of extents. The code (only) works around all these + issues if $count is "undef". aio_group $callback->(...) This is a very special aio request: Instead of doing something, it @@ -1130,9 +1204,9 @@ }; }; - That "aio_wd" is a request and not a normal function shows that creating - an IO::AIO::WD object is itself a potentially blocking operation, which - is why it is done asynchronously. + The fact that "aio_wd" is a request and not a normal function shows that + creating an IO::AIO::WD object is itself a potentially blocking + operation, which is why it is done asynchronously. To stat the directory obtained with "aio_wd" above, one could write either of the following three request calls: @@ -1159,8 +1233,8 @@ nowhere at all), while the directory fd, if available on the system, will still point to the original directory. Most functions accepting a pathname will use the directory fd on newer systems, and the string on - older systems. Some functions (such as realpath) will always rely on the - string form of the pathname. + older systems. Some functions (such as "aio_realpath") will always rely + on the string form of the pathname. So this functionality is mainly useful to get some protection against "chdir", to easily get an absolute path out of a relative path for @@ -1183,7 +1257,7 @@ value will fail in the expected way. IO::AIO::CWD - This is a compiletime constant (object) that represents the process + This is a compile time constant (object) that represents the process current working directory. Specifying this object as working directory object for a pathname is @@ -1418,6 +1492,17 @@ IO::AIO::poll_wait, IO::AIO::poll_cb while IO::AIO::nreqs; + This function can be useful at program aborts, to make sure + outstanding I/O has been done ("IO::AIO" uses an "END" block which + already calls this function on normal exits), or when you are merely + using "IO::AIO" for its more advanced functions, rather than for + async I/O, e.g.: + + my ($dirs, $nondirs); + IO::AIO::aio_scandir "/tmp", 0, sub { ($dirs, $nondirs) = @_ }; + IO::AIO::flush; + # $dirs, $nondirs are now set + IO::AIO::max_poll_reqs $nreqs IO::AIO::max_poll_time $seconds These set the maximum number of requests (default 0, meaning @@ -1516,12 +1601,14 @@ In other words, this setting does not enforce a queue limit, but can be used to make poll functions block if the limit is exceeded. - This is a very bad function to use in interactive programs because - it blocks, and a bad way to reduce concurrency because it is - inexact: Better use an "aio_group" together with a feed callback. + This is a bad function to use in interactive programs because it + blocks, and a bad way to reduce concurrency because it is inexact. + If you need to issue many requests without being able to call a poll + function on demand, it is better to use an "aio_group" together with + a feed callback. - It's main use is in scripts without an event loop - when you want to - stat a lot of files, you can write somehting like this: + Its main use is in scripts without an event loop - when you want to + stat a lot of files, you can write something like this: IO::AIO::max_outstanding 32; @@ -1533,10 +1620,11 @@ IO::AIO::flush; The call to "poll_cb" inside the loop will normally return - instantly, but as soon as more thna 32 reqeusts are in-flight, it - will block until some requests have been handled. This keeps the - loop from pushing a large number of "aio_stat" requests onto the - queue. + instantly, allowing the loop to progress, but as soon as more than + 32 requests are in-flight, it will block until some requests have + been handled. This keeps the loop from pushing a large number of + "aio_stat" requests onto the queue (which, with many paths to stat, + can use up a lot of memory). The default value for "max_outstanding" is very large, so there is no practical limit on the number of outstanding requests. @@ -1560,9 +1648,152 @@ Returns the number of requests currently in the pending state (executed, but not yet processed by poll_cb). + SUBSECOND STAT TIME ACCESS + Both "aio_stat"/"aio_lstat" and perl's "stat"/"lstat" functions can + generally find access/modification and change times with subsecond time + accuracy of the system supports it, but perl's built-in functions only + return the integer part. + + The following functions return the timestamps of the most recent stat + with subsecond precision on most systems and work both after + "aio_stat"/"aio_lstat" and perl's "stat"/"lstat" calls. Their return + value is only meaningful after a successful "stat"/"lstat" call, or + during/after a successful "aio_stat"/"aio_lstat" callback. + + This is similar to the Time::HiRes "stat" functions, but can return full + resolution without rounding and work with standard perl "stat", + alleviating the need to call the special "Time::HiRes" functions, which + do not act like their perl counterparts. + + On operating systems or file systems where subsecond time resolution is + not supported or could not be detected, a fractional part of 0 is + returned, so it is always safe to call these functions. + + $seconds = IO::AIO::st_atime, IO::AIO::st_mtime, IO::AIO::st_ctime, + IO::AIO::st_btime + Return the access, modication, change or birth time, respectively, + including fractional part. Due to the limited precision of floating + point, the accuracy on most platforms is only a bit better than + milliseconds for times around now - see the *nsec* function family, + below, for full accuracy. + + File birth time is only available when the OS and perl support it + (on FreeBSD and NetBSD at the time of this writing, although support + is adaptive, so if your OS/perl gains support, IO::AIO can take + advantage of it). On systems where it isn't available, 0 is + currently returned, but this might change to "undef" in a future + version. + + ($atime, $mtime, $ctime, $btime, ...) = IO::AIO::st_xtime + Returns access, modification, change and birth time all in one go, + and maybe more times in the future version. + + $nanoseconds = IO::AIO::st_atimensec, IO::AIO::st_mtimensec, + IO::AIO::st_ctimensec, IO::AIO::st_btimensec + Return the fractional access, modifcation, change or birth time, in + nanoseconds, as an integer in the range 0 to 999999999. + + Note that no accessors are provided for access, modification and + change times - you need to get those from "stat _" if required ("int + IO::AIO::st_atime" and so on will *not* generally give you the + correct value). + + $seconds = IO::AIO::st_btimesec + The (integral) seconds part of the file birth time, if available. + + ($atime, $mtime, $ctime, $btime, ...) = IO::AIO::st_xtimensec + Like the functions above, but returns all four times in one go (and + maybe more in future versions). + + $counter = IO::AIO::st_gen + Returns the generation counter (in practice this is just a random + number) of the file. This is only available on platforms which have + this member in their "struct stat" (most BSDs at the time of this + writing) and generally only to the root usert. If unsupported, 0 is + returned, but this might change to "undef" in a future version. + + Example: print the high resolution modification time of /etc, using + "stat", and "IO::AIO::aio_stat". + + if (stat "/etc") { + printf "stat(/etc) mtime: %f\n", IO::AIO::st_mtime; + } + + IO::AIO::aio_stat "/etc", sub { + $_[0] + and return; + + printf "aio_stat(/etc) mtime: %d.%09d\n", (stat _)[9], IO::AIO::st_mtimensec; + }; + + IO::AIO::flush; + + Output of the awbove on my system, showing reduced and full accuracy: + + stat(/etc) mtime: 1534043702.020808 + aio_stat(/etc) mtime: 1534043702.020807792 + MISCELLANEOUS FUNCTIONS - IO::AIO implements some functions that might be useful, but are not - asynchronous. + IO::AIO implements some functions that are useful when you want to use + some "Advanced I/O" function not available to in Perl, without going the + "Asynchronous I/O" route. Many of these have an asynchronous "aio_*" + counterpart. + + $retval = IO::AIO::fexecve $fh, $argv, $envp + A more-or-less direct equivalent to the POSIX "fexecve" functions, + which allows you to specify the program to be executed via a file + descriptor (or handle). Returns -1 and sets errno to "ENOSYS" if not + available. + + $retval = IO::AIO::mount $special, $path, $fstype, $flags = 0, $data = + undef + Calls the GNU/Linux mount syscall with the given arguments. All + except $flags are strings, and if $data is "undef", a "NULL" will be + passed. + + The following values for $flags are available: + + "IO::AIO::MS_RDONLY", "IO::AIO::MS_NOSUID", "IO::AIO::MS_NODEV", + "IO::AIO::MS_NOEXEC", "IO::AIO::MS_SYNCHRONOUS", + "IO::AIO::MS_REMOUNT", "IO::AIO::MS_MANDLOCK", + "IO::AIO::MS_DIRSYNC", "IO::AIO::MS_NOATIME", + "IO::AIO::MS_NODIRATIME", "IO::AIO::MS_BIND", "IO::AIO::MS_MOVE", + "IO::AIO::MS_REC", "IO::AIO::MS_SILENT", "IO::AIO::MS_POSIXACL", + "IO::AIO::MS_UNBINDABLE", "IO::AIO::MS_PRIVATE", + "IO::AIO::MS_SLAVE", "IO::AIO::MS_SHARED", "IO::AIO::MS_RELATIME", + "IO::AIO::MS_KERNMOUNT", "IO::AIO::MS_I_VERSION", + "IO::AIO::MS_STRICTATIME", "IO::AIO::MS_LAZYTIME", + "IO::AIO::MS_ACTIVE", "IO::AIO::MS_NOUSER", "IO::AIO::MS_RMT_MASK", + "IO::AIO::MS_MGC_VAL" and "IO::AIO::MS_MGC_MSK". + + $retval = IO::AIO::umount $path, $flags = 0 + Invokes the GNU/Linux "umount" or "umount2" syscalls. Always calls + "umount" if $flags is 0, otherwqise always tries to call "umount2". + + The following $flags are available: + + "IO::AIO::MNT_FORCE", "IO::AIO::MNT_DETACH", "IO::AIO::MNT_EXPIRE" + and "IO::AIO::UMOUNT_NOFOLLOW". + + $numfd = IO::AIO::get_fdlimit + Tries to find the current file descriptor limit and returns it, or + "undef" and sets $! in case of an error. The limit is one larger + than the highest valid file descriptor number. + + IO::AIO::min_fdlimit [$numfd] + Try to increase the current file descriptor limit(s) to at least + $numfd by changing the soft or hard file descriptor resource limit. + If $numfd is missing, it will try to set a very high limit, although + this is not recommended when you know the actual minimum that you + require. + + If the limit cannot be raised enough, the function makes a + best-effort attempt to increase the limit as much as possible, using + various tricks, while still failing. You can query the resulting + limit using "IO::AIO::get_fdlimit". + + If an error occurs, returns "undef" and sets $!, otherwise returns + true. IO::AIO::sendfile $ofh, $ifh, $offset, $count Calls the "eio_sendfile_sync" function, which is like @@ -1589,6 +1820,10 @@ "IO::AIO::MADV_RANDOM", "IO::AIO::MADV_WILLNEED", "IO::AIO::MADV_DONTNEED". + If $offset is negative, counts from the end. If $length is negative, + the remaining length of the $scalar is used. If possible, $length + will be reduced to fit into the $scalar. + On systems that do not implement "posix_madvise", this function returns ENOSYS, otherwise the return value of "posix_madvise". @@ -1598,6 +1833,10 @@ constants are available: "IO::AIO::PROT_NONE", "IO::AIO::PROT_READ", "IO::AIO::PROT_WRITE", "IO::AIO::PROT_EXEC". + If $offset is negative, counts from the end. If $length is negative, + the remaining length of the $scalar is used. If possible, $length + will be reduced to fit into the $scalar. + On systems that do not implement "mprotect", this function returns ENOSYS, otherwise the return value of "mprotect". @@ -1606,15 +1845,20 @@ the given $scalar, which will act like a string scalar. Returns true on success, and false otherwise. - The only operations allowed on the scalar are "substr"/"vec" that - don't change the string length, and most read-only operations such - as copying it or searching it with regexes and so on. + The scalar must exist, but its contents do not matter - this means + you cannot use a nonexistant array or hash element. When in doubt, + "undef" the scalar first. + + The only operations allowed on the mmapped scalar are + "substr"/"vec", which don't change the string length, and most + read-only operations such as copying it or searching it with regexes + and so on. Anything else is unsafe and will, at best, result in memory leaks. The memory map associated with the $scalar is automatically removed - when the $scalar is destroyed, or when the "IO::AIO::mmap" or - "IO::AIO::munmap" functions are called. + when the $scalar is undef'd or destroyed, or when the + "IO::AIO::mmap" or "IO::AIO::munmap" functions are called on it. This calls the "mmap"(2) function internally. See your system's manual page for details on the $length, $prot and $flags parameters. @@ -1628,11 +1872,14 @@ $flags can be a combination of "IO::AIO::MAP_SHARED" or "IO::AIO::MAP_PRIVATE", or a number of system-specific flags (when - not available, the are defined as 0): "IO::AIO::MAP_ANONYMOUS" - (which is set to "MAP_ANON" if your system only provides this - constant), "IO::AIO::MAP_HUGETLB", "IO::AIO::MAP_LOCKED", - "IO::AIO::MAP_NORESERVE", "IO::AIO::MAP_POPULATE" or - "IO::AIO::MAP_NONBLOCK" + not available, the are 0): "IO::AIO::MAP_ANONYMOUS" (which is set to + "MAP_ANON" if your system only provides this constant), + "IO::AIO::MAP_LOCKED", "IO::AIO::MAP_NORESERVE", + "IO::AIO::MAP_POPULATE", "IO::AIO::MAP_NONBLOCK", + "IO::AIO::MAP_FIXED", "IO::AIO::MAP_GROWSDOWN", + "IO::AIO::MAP_32BIT", "IO::AIO::MAP_HUGETLB", "IO::AIO::MAP_STACK", + "IO::AIO::MAP_FIXED_NOREPLACE", "IO::AIO::MAP_SHARED_VALIDATE", + "IO::AIO::MAP_SYNC" or "IO::AIO::MAP_UNINITIALIZED". If $fh is "undef", then a file descriptor of -1 is passed. @@ -1655,6 +1902,34 @@ IO::AIO::munmap $scalar Removes a previous mmap and undefines the $scalar. + IO::AIO::mremap $scalar, $new_length, $flags = MREMAP_MAYMOVE[, + $new_address = 0] + Calls the Linux-specific mremap(2) system call. The $scalar must + have been mapped by "IO::AIO::mmap", and $flags must currently + either be 0 or "IO::AIO::MREMAP_MAYMOVE". + + Returns true if successful, and false otherwise. If the underlying + mmapped region has changed address, then the true value has the + numerical value 1, otherwise it has the numerical value 0: + + my $success = IO::AIO::mremap $mmapped, 8192, IO::AIO::MREMAP_MAYMOVE + or die "mremap: $!"; + + if ($success*1) { + warn "scalar has chanegd address in memory\n"; + } + + "IO::AIO::MREMAP_FIXED" and the $new_address argument are currently + implemented, but not supported and might go away in a future + version. + + On systems where this call is not supported or is not emulated, this + call returns falls and sets $! to "ENOSYS". + + IO::AIO::mlockall $flags + Calls the "eio_mlockall_sync" function, which is like + "aio_mlockall", but is blocking. + IO::AIO::munlock $scalar, $offset = 0, $length = undef Calls the "munlock" function, undoing the effects of a previous "aio_mlock" call (see its description for details). @@ -1665,6 +1940,26 @@ On systems that do not implement "munlockall", this function returns ENOSYS, otherwise the return value of "munlockall". + $fh = IO::AIO::accept4 $r_fh, $sockaddr, $sockaddr_maxlen, $flags + Uses the GNU/Linux accept4(2) syscall, if available, to accept a + socket and return the new file handle on success, or sets $! and + returns "undef" on error. + + The remote name of the new socket will be stored in $sockaddr, which + will be extended to allow for at least $sockaddr_maxlen octets. If + the socket name does not fit into $sockaddr_maxlen octets, this is + signaled by returning a longer string in $sockaddr, which might or + might not be truncated. + + To accept name-less sockets, use "undef" for $sockaddr and 0 for + $sockaddr_maxlen. + + The main reasons to use this syscall rather than portable accept(2) + are that you can specify "SOCK_NONBLOCK" and/or "SOCK_CLOEXEC" flags + and you can accept name-less sockets by specifying 0 for + $sockaddr_maxlen, which is sadly not possible with perl's interface + to "accept". + IO::AIO::splice $r_fh, $r_off, $w_fh, $w_off, $length, $flags Calls the GNU/Linux splice(2) syscall, if available. If $r_off or $w_off are "undef", then "NULL" is passed for these, otherwise they @@ -1680,7 +1975,7 @@ See the splice(2) manpage for details. IO::AIO::tee $r_fh, $w_fh, $length, $flags - Calls the GNU/Linux tee(2) syscall, see it's manpage and the + Calls the GNU/Linux tee(2) syscall, see its manpage and the description for "IO::AIO::splice" above for details. $actual_size = IO::AIO::pipesize $r_fh[, $new_size] @@ -1689,6 +1984,187 @@ fails with -1/"ENOSYS" everywhere else. If anybody knows how to influence pipe buffer size on other systems, drop me a note. + ($rfh, $wfh) = IO::AIO::pipe2 [$flags] + This is a direct interface to the Linux pipe2(2) system call. If + $flags is missing or 0, then this should be the same as a call to + perl's built-in "pipe" function and create a new pipe, and works on + systems that lack the pipe2 syscall. On win32, this case invokes + "_pipe (..., 4096, O_BINARY)". + + If $flags is non-zero, it tries to invoke the pipe2 system call with + the given flags (Linux 2.6.27, glibc 2.9). + + On success, the read and write file handles are returned. + + On error, nothing will be returned. If the pipe2 syscall is missing + and $flags is non-zero, fails with "ENOSYS". + + Please refer to pipe2(2) for more info on the $flags, but at the + time of this writing, "IO::AIO::O_CLOEXEC", "IO::AIO::O_NONBLOCK" + and "IO::AIO::O_DIRECT" (Linux 3.4, for packet-based pipes) were + supported. + + Example: create a pipe race-free w.r.t. threads and fork: + + my ($rfh, $wfh) = IO::AIO::pipe2 IO::AIO::O_CLOEXEC + or die "pipe2: $!\n"; + + $fh = IO::AIO::memfd_create $pathname[, $flags] + This is a direct interface to the Linux memfd_create(2) system call. + The (unhelpful) default for $flags is 0, but your default should be + "IO::AIO::MFD_CLOEXEC". + + On success, the new memfd filehandle is returned, otherwise returns + "undef". If the memfd_create syscall is missing, fails with + "ENOSYS". + + Please refer to memfd_create(2) for more info on this call. + + The following $flags values are available: "IO::AIO::MFD_CLOEXEC", + "IO::AIO::MFD_ALLOW_SEALING", "IO::AIO::MFD_HUGETLB", + "IO::AIO::MFD_HUGETLB_2MB" and "IO::AIO::MFD_HUGETLB_1GB". + + Example: create a new memfd. + + my $fh = IO::AIO::memfd_create "somenameforprocfd", IO::AIO::MFD_CLOEXEC + or die "memfd_create: $!\n"; + + $fh = IO::AIO::pidfd_open $pid[, $flags] + This is an interface to the Linux pidfd_open(2) system call. The + default for $flags is 0. + + On success, a new pidfd filehandle is returned (that is already set + to close-on-exec), otherwise returns "undef". If the syscall is + missing, fails with "ENOSYS". + + Example: open pid 6341 as pidfd. + + my $fh = IO::AIO::pidfd_open 6341 + or die "pidfd_open: $!\n"; + + $status = IO::AIO::pidfd_send_signal $pidfh, $signal[, $siginfo[, + $flags]] + This is an interface to the Linux pidfd_send_signal system call. The + default for $siginfo is "undef" and the default for $flags is 0. + + Returns the system call status. If the syscall is missing, fails + with "ENOSYS". + + When specified, $siginfo must be a reference to a hash with one or + more of the following members: + + code - the "si_code" member + pid - the "si_pid" member + uid - the "si_uid" member + value_int - the "si_value.sival_int" member + value_ptr - the "si_value.sival_ptr" member, specified as an integer + + Example: send a SIGKILL to the specified process. + + my $status = IO::AIO::pidfd_send_signal $pidfh, 9, undef + and die "pidfd_send_signal: $!\n"; + + Example: send a SIGKILL to the specified process with extra data. + + my $status = IO::AIO::pidfd_send_signal $pidfh, 9, { code => -1, value_int => 7 } + and die "pidfd_send_signal: $!\n"; + + $fh = IO::AIO::pidfd_getfd $pidfh, $targetfd[, $flags] + This is an interface to the Linux pidfd_getfd system call. The + default for $flags is 0. + + On success, returns a dup'ed copy of the target file descriptor + (specified as an integer) returned (that is already set to + close-on-exec), otherwise returns "undef". If the syscall is + missing, fails with "ENOSYS". + + Example: get a copy of standard error of another process and print + soemthing to it. + + my $errfh = IO::AIO::pidfd_getfd $pidfh, 2 + or die "pidfd_getfd: $!\n"; + print $errfh "stderr\n"; + + $fh = IO::AIO::eventfd [$initval, [$flags]] + This is a direct interface to the Linux eventfd(2) system call. The + (unhelpful) defaults for $initval and $flags are 0 for both. + + On success, the new eventfd filehandle is returned, otherwise + returns "undef". If the eventfd syscall is missing, fails with + "ENOSYS". + + Please refer to eventfd(2) for more info on this call. + + The following symbol flag values are available: + "IO::AIO::EFD_CLOEXEC", "IO::AIO::EFD_NONBLOCK" and + "IO::AIO::EFD_SEMAPHORE" (Linux 2.6.30). + + Example: create a new eventfd filehandle: + + $fh = IO::AIO::eventfd 0, IO::AIO::EFD_CLOEXEC + or die "eventfd: $!\n"; + + $fh = IO::AIO::timerfd_create $clockid[, $flags] + This is a direct interface to the Linux timerfd_create(2) system + call. The (unhelpful) default for $flags is 0, but your default + should be "IO::AIO::TFD_CLOEXEC". + + On success, the new timerfd filehandle is returned, otherwise + returns "undef". If the timerfd_create syscall is missing, fails + with "ENOSYS". + + Please refer to timerfd_create(2) for more info on this call. + + The following $clockid values are available: + "IO::AIO::CLOCK_REALTIME", "IO::AIO::CLOCK_MONOTONIC" + "IO::AIO::CLOCK_CLOCK_BOOTTIME" (Linux 3.15) + "IO::AIO::CLOCK_CLOCK_REALTIME_ALARM" (Linux 3.11) and + "IO::AIO::CLOCK_CLOCK_BOOTTIME_ALARM" (Linux 3.11). + + The following $flags values are available (Linux 2.6.27): + "IO::AIO::TFD_NONBLOCK" and "IO::AIO::TFD_CLOEXEC". + + Example: create a new timerfd and set it to one-second repeated + alarms, then wait for two alarms: + + my $fh = IO::AIO::timerfd_create IO::AIO::CLOCK_BOOTTIME, IO::AIO::TFD_CLOEXEC + or die "timerfd_create: $!\n"; + + defined IO::AIO::timerfd_settime $fh, 0, 1, 1 + or die "timerfd_settime: $!\n"; + + for (1..2) { + 8 == sysread $fh, my $buf, 8 + or die "timerfd read failure\n"; + + printf "number of expirations (likely 1): %d\n", + unpack "Q", $buf; + } + + ($cur_interval, $cur_value) = IO::AIO::timerfd_settime $fh, $flags, + $new_interval, $nbw_value + This is a direct interface to the Linux timerfd_settime(2) system + call. Please refer to its manpage for more info on this call. + + The new itimerspec is specified using two (possibly fractional) + second values, $new_interval and $new_value). + + On success, the current interval and value are returned (as per + "timerfd_gettime"). On failure, the empty list is returned. + + The following $flags values are available: + "IO::AIO::TFD_TIMER_ABSTIME" and "IO::AIO::TFD_TIMER_CANCEL_ON_SET". + + See "IO::AIO::timerfd_create" for a full example. + + ($cur_interval, $cur_value) = IO::AIO::timerfd_gettime $fh + This is a direct interface to the Linux timerfd_gettime(2) system + call. Please refer to its manpage for more info on this call. + + On success, returns the current values of interval and value for the + given timerfd (as potentially fractional second values). On failure, + the empty list is returned. + EVENT LOOP INTEGRATION It is recommended to use AnyEvent::AIO to integrate IO::AIO automatically into many event loops: @@ -1747,6 +2223,14 @@ Calling it at any time will also result in any undefined (by POSIX) behaviour. + LINUX-SPECIFIC CALLS + When a call is documented as "linux-specific" then this means it + originated on GNU/Linux. "IO::AIO" will usually try to autodetect the + availability and compatibility of such calls regardless of the platform + it is compiled on, so platforms such as FreeBSD which often implement + these calls will work. When in doubt, call them and see if they fail wth + "ENOSYS". + MEMORY USAGE Per-request usage: @@ -1766,11 +2250,21 @@ structures (usually around 16k-128k, depending on the OS). KNOWN BUGS - Known bugs will be fixed in the next release. + Known bugs will be fixed in the next release :) + +KNOWN ISSUES + Calls that try to "import" foreign memory areas (such as "IO::AIO::mmap" + or "IO::AIO::aio_slurp") do not work with generic lvalues, such as + non-created hash slots or other scalars I didn't think of. It's best to + avoid such and either use scalar variables or making sure that the + scalar exists (e.g. by storing "undef") and isn't "funny" (e.g. tied). + + I am not sure anything can be done about this, so this is considered a + known issue, rather than a bug. SEE ALSO AnyEvent::AIO for easy integration into event loops, Coro::AIO for a - more natural syntax. + more natural syntax and IO::FDPass for file descriptor passing. AUTHOR Marc Lehmann