mirror of
git://git.musl-libc.org/musl
synced 2025-02-22 13:56:49 +00:00
remove cancellation points in stdio
commit 5816592389
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.
This commit is contained in:
parent
536c6d5a42
commit
4ef9b828c1
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user