about summary refs log tree commit diff
path: root/src/unistd
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-02-13 00:27:45 -0500
committerRich Felker <dalias@aerifal.cx>2015-02-13 01:10:11 -0500
commit4e8a3561652ebcda6a126b3162fc545573889dc4 (patch)
treeeb83d08f7b14a6c160118c053452e9cb7774833f /src/unistd
parent594ffed82f4e6ee7da85e9c5da35e32946ae32c9 (diff)
downloadmusl-4e8a3561652ebcda6a126b3162fc545573889dc4.tar.gz
musl-4e8a3561652ebcda6a126b3162fc545573889dc4.tar.xz
musl-4e8a3561652ebcda6a126b3162fc545573889dc4.zip
overhaul aio implementation for correctness
previously, aio operations were not tracked by file descriptor; each
operation was completely independent. this resulted in non-conforming
behavior for non-seekable/append-mode writes (which are required to be
ordered) and made it impossible to implement aio_cancel, which in turn
made closing file descriptors with outstanding aio operations unsafe.

the new implementation is significantly heavier (roughly twice the
size, and seems to be slightly slower) and presently aims mainly at
correctness, not performance.

most of the public interfaces have been moved into a single file,
aio.c, because there is little benefit to be had from splitting them.
whenever any aio functions are used, aio_cancel and the internal
queue lifetime management and fd-to-queue mapping code must be linked,
and these functions make up the bulk of the code size.

the close function's interaction with aio is implemented with weak
alias magic, to avoid pulling in heavy aio cancellation code in
programs that don't use aio, and the expensive cancellation path
(which includes signal blocking) is optimized out when there are no
active aio queues.
Diffstat (limited to 'src/unistd')
-rw-r--r--src/unistd/close.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/unistd/close.c b/src/unistd/close.c
index e8f813d6..2f1eabd7 100644
--- a/src/unistd/close.c
+++ b/src/unistd/close.c
@@ -3,8 +3,16 @@
 #include "syscall.h"
 #include "libc.h"
 
+static int dummy(int fd)
+{
+	return fd;
+}
+
+weak_alias(dummy, __aio_close);
+
 int close(int fd)
 {
+	fd = __aio_close(fd);
 	int r = __syscall_cp(SYS_close, fd);
 	if (r == -EINTR) r = -EINPROGRESS;
 	return __syscall_ret(r);