summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-06-13 20:53:02 +0000
committerRich Felker <dalias@aerifal.cx>2015-06-13 20:53:02 +0000
commit4ef9b828c1f39553a69e0635ac91f0fcadd6e8c6 (patch)
tree4f673b8ddbae50ca7072b600466051c347df1fc2
parent536c6d5a4205e2a3f161f2983ce1e0ac3082187d (diff)
downloadmusl-4ef9b828c1f39553a69e0635ac91f0fcadd6e8c6.tar.gz
remove cancellation points in stdio
commit 58165923890865a6ac042fafce13f440ee986fd9 added these optional cancellation points on the basis that cancellable stdio could be useful, to unblock threads stuck on stdio operations that will never complete. however, the only way to ensure that cancellation can achieve this is to violate the rules for side effects when cancellation is acted upon, discarding knowledge of any partial data transfer already completed. our implementation exhibited this behavior and was thus non-conforming. in addition to improving correctness, removing these cancellation points moderately reduces code size, and should significantly improve performance on i386, where sysenter/syscall instructions can be used instead of "int $128" for non-cancellable syscalls.
-rw-r--r--src/stdio/__stdio_read.c11
-rw-r--r--src/stdio/__stdio_write.c14
-rw-r--r--src/stdio/fopen.c2
3 files changed, 3 insertions, 24 deletions
diff --git a/src/stdio/__stdio_read.c b/src/stdio/__stdio_read.c
index 59473444..f8fa6d3b 100644
--- a/src/stdio/__stdio_read.c
+++ b/src/stdio/__stdio_read.c
@@ -1,12 +1,5 @@
#include "stdio_impl.h"
#include <sys/uio.h>
-#include <pthread.h>
-
-static void cleanup(void *p)
-{
- FILE *f = p;
- if (!f->lockcount) __unlockfile(f);
-}
size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
{
@@ -16,9 +9,7 @@ size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
};
ssize_t cnt;
- pthread_cleanup_push(cleanup, f);
- cnt = syscall_cp(SYS_readv, f->fd, iov, 2);
- pthread_cleanup_pop(0);
+ cnt = syscall(SYS_readv, f->fd, iov, 2);
if (cnt <= 0) {
f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt);
return cnt;
diff --git a/src/stdio/__stdio_write.c b/src/stdio/__stdio_write.c
index 8c89389a..d2d89475 100644
--- a/src/stdio/__stdio_write.c
+++ b/src/stdio/__stdio_write.c
@@ -1,12 +1,5 @@
#include "stdio_impl.h"
#include <sys/uio.h>
-#include <pthread.h>
-
-static void cleanup(void *p)
-{
- FILE *f = p;
- if (!f->lockcount) __unlockfile(f);
-}
size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
{
@@ -19,9 +12,7 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
int iovcnt = 2;
ssize_t cnt;
for (;;) {
- pthread_cleanup_push(cleanup, f);
- cnt = syscall_cp(SYS_writev, f->fd, iov, iovcnt);
- pthread_cleanup_pop(0);
+ cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
if (cnt == rem) {
f->wend = f->buf + f->buf_size;
f->wpos = f->wbase = f->buf;
@@ -34,11 +25,8 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
}
rem -= cnt;
if (cnt > iov[0].iov_len) {
- f->wpos = f->wbase = f->buf;
cnt -= iov[0].iov_len;
iov++; iovcnt--;
- } else if (iovcnt == 2) {
- f->wbase += cnt;
}
iov[0].iov_base = (char *)iov[0].iov_base + cnt;
iov[0].iov_len -= cnt;
diff --git a/src/stdio/fopen.c b/src/stdio/fopen.c
index 07bdb6e8..252f0824 100644
--- a/src/stdio/fopen.c
+++ b/src/stdio/fopen.c
@@ -18,7 +18,7 @@ FILE *fopen(const char *restrict filename, const char *restrict mode)
/* Compute the flags to pass to open() */
flags = __fmodeflags(mode);
- fd = sys_open_cp(filename, flags, 0666);
+ fd = sys_open(filename, flags, 0666);
if (fd < 0) return 0;
if (flags & O_CLOEXEC)
__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);