mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-03 09:01:50 -05:00
try to use send(,,MSG_NOSIGNAL) instead of write() wherever possible (which
will allow us to drop the SIGPIPE check). Cache the results of the last write()/send() to make sure that we do not issue more than necessary system calls. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1083 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
350a253dc5
commit
860be2e70b
17 changed files with 100 additions and 58 deletions
|
|
@ -53,7 +53,7 @@ static int generate(int fd, void *ret_data, size_t length) {
|
|||
lseek(fd, 0, SEEK_SET);
|
||||
ftruncate(fd, 0);
|
||||
|
||||
if ((r = pa_loop_write(fd, ret_data, length)) < 0 || (size_t) r != length) {
|
||||
if ((r = pa_loop_write(fd, ret_data, length, NULL)) < 0 || (size_t) r != length) {
|
||||
pa_log(__FILE__": failed to write cookie file: %s", pa_cstrerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ static int load(const char *fn, void *data, size_t length) {
|
|||
|
||||
unlock = pa_lock_fd(fd, 1) >= 0;
|
||||
|
||||
if ((r = pa_loop_read(fd, data, length)) < 0) {
|
||||
if ((r = pa_loop_read(fd, data, length, NULL)) < 0) {
|
||||
pa_log(__FILE__": failed to read cookie file '%s': %s", fn, pa_cstrerror(errno));
|
||||
goto finish;
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@ int pa_authkey_save(const char *fn, const void *data, size_t length) {
|
|||
|
||||
unlock = pa_lock_fd(fd, 1) >= 0;
|
||||
|
||||
if ((r = pa_loop_write(fd, data, length)) < 0 || (size_t) r != length) {
|
||||
if ((r = pa_loop_write(fd, data, length, NULL)) < 0 || (size_t) r != length) {
|
||||
pa_log(__FILE__": failed to read cookie file '%s': %s", fn, pa_cstrerror(errno));
|
||||
goto finish;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,57 +201,81 @@ finish:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/** Platform independent read function. Necessary since not all systems
|
||||
* treat all file descriptors equal. */
|
||||
ssize_t pa_read(int fd, void *buf, size_t count) {
|
||||
ssize_t r;
|
||||
/** Platform independent read function. Necessary since not all
|
||||
* systems treat all file descriptors equal. If type is
|
||||
* non-NULL it is used to cache the type of the fd. This is
|
||||
* useful for making sure that only a single syscall is executed per
|
||||
* function call. The variable pointed to should be initialized to 0
|
||||
* by the caller. */
|
||||
ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
r = recv(fd, buf, count, 0);
|
||||
if (r < 0) {
|
||||
|
||||
if (!type || *type == 0) {
|
||||
ssize_t r;
|
||||
|
||||
if ((r = recv(fd, buf, count, 0)) >= 0)
|
||||
return r;
|
||||
|
||||
if (WSAGetLastError() != WSAENOTSOCK) {
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
||||
if (type)
|
||||
*type = 1;
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
#endif
|
||||
r = read(fd, buf, count);
|
||||
|
||||
return r;
|
||||
|
||||
return read(fd, buf, count);
|
||||
}
|
||||
|
||||
/** Similar to pa_read(), but handles writes */
|
||||
ssize_t pa_write(int fd, const void *buf, size_t count) {
|
||||
ssize_t r;
|
||||
ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
|
||||
|
||||
if (!type || *type == 0) {
|
||||
ssize_t r;
|
||||
|
||||
if ((r = send(fd, buf, count, MSG_NOSIGNAL)) >= 0)
|
||||
return r;
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
r = send(fd, buf, count, 0);
|
||||
if (r < 0) {
|
||||
if (WSAGetLastError() != WSAENOTSOCK) {
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
if (errno != ENOTSOCK)
|
||||
return r;
|
||||
#endif
|
||||
|
||||
if (type)
|
||||
*type = 1;
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
#endif
|
||||
r = write(fd, buf, count);
|
||||
|
||||
return r;
|
||||
return write(fd, buf, count);
|
||||
}
|
||||
|
||||
/** Calls read() in a loop. Makes sure that as much as 'size' bytes,
|
||||
* unless EOF is reached or an error occured */
|
||||
ssize_t pa_loop_read(int fd, void*data, size_t size) {
|
||||
ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
|
||||
ssize_t ret = 0;
|
||||
assert(fd >= 0 && data && size);
|
||||
int _type;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(data);
|
||||
assert(size);
|
||||
|
||||
if (!type) {
|
||||
_type = 0;
|
||||
type = &_type;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
ssize_t r;
|
||||
|
||||
if ((r = pa_read(fd, data, size)) < 0)
|
||||
if ((r = pa_read(fd, data, size, type)) < 0)
|
||||
return r;
|
||||
|
||||
if (r == 0)
|
||||
|
|
@ -266,14 +290,23 @@ ssize_t pa_loop_read(int fd, void*data, size_t size) {
|
|||
}
|
||||
|
||||
/** Similar to pa_loop_read(), but wraps write() */
|
||||
ssize_t pa_loop_write(int fd, const void*data, size_t size) {
|
||||
ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
|
||||
ssize_t ret = 0;
|
||||
assert(fd >= 0 && data && size);
|
||||
int _type;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(data);
|
||||
assert(size);
|
||||
|
||||
if (!type) {
|
||||
_type = 0;
|
||||
type = &_type;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
ssize_t r;
|
||||
|
||||
if ((r = pa_write(fd, data, size)) < 0)
|
||||
if ((r = pa_write(fd, data, size, type)) < 0)
|
||||
return r;
|
||||
|
||||
if (r == 0)
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ void pa_make_nonblock_fd(int fd);
|
|||
int pa_make_secure_dir(const char* dir);
|
||||
int pa_make_secure_parent_dir(const char *fn);
|
||||
|
||||
ssize_t pa_read(int fd, void *buf, size_t count);
|
||||
ssize_t pa_write(int fd, const void *buf, size_t count);
|
||||
ssize_t pa_loop_read(int fd, void*data, size_t size);
|
||||
ssize_t pa_loop_write(int fd, const void*data, size_t size);
|
||||
ssize_t pa_read(int fd, void *buf, size_t count, int *type);
|
||||
ssize_t pa_write(int fd, const void *buf, size_t count, int *type);
|
||||
ssize_t pa_loop_read(int fd, void*data, size_t size, int *type);
|
||||
ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type);
|
||||
|
||||
void pa_check_signal_is_blocked(int sig);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
struct pa_iochannel {
|
||||
int ifd, ofd;
|
||||
int ifd_type, ofd_type;
|
||||
pa_mainloop_api* mainloop;
|
||||
|
||||
pa_iochannel_cb_t callback;
|
||||
|
|
@ -127,6 +128,7 @@ pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) {
|
|||
io = pa_xnew(pa_iochannel, 1);
|
||||
io->ifd = ifd;
|
||||
io->ofd = ofd;
|
||||
io->ifd_type = io->ofd_type = 0;
|
||||
io->mainloop = m;
|
||||
|
||||
io->userdata = NULL;
|
||||
|
|
@ -204,7 +206,7 @@ ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) {
|
|||
assert(l);
|
||||
assert(io->ofd >= 0);
|
||||
|
||||
r = pa_write(io->ofd, data, l);
|
||||
r = pa_write(io->ofd, data, l, &io->ofd_type);
|
||||
if (r >= 0) {
|
||||
io->writable = 0;
|
||||
enable_mainloop_sources(io);
|
||||
|
|
@ -220,7 +222,7 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) {
|
|||
assert(data);
|
||||
assert(io->ifd >= 0);
|
||||
|
||||
r = pa_read(io->ifd, data, l);
|
||||
r = pa_read(io->ifd, data, l, &io->ifd_type);
|
||||
if (r >= 0) {
|
||||
io->readable = 0;
|
||||
enable_mainloop_sources(io);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ static pid_t read_pid(const char *fn, int fd) {
|
|||
|
||||
assert(fn && fd >= 0);
|
||||
|
||||
if ((r = pa_loop_read(fd, t, sizeof(t)-1)) < 0) {
|
||||
if ((r = pa_loop_read(fd, t, sizeof(t)-1, NULL)) < 0) {
|
||||
pa_log_warn(__FILE__": WARNING: failed to read PID file '%s': %s",
|
||||
fn, pa_cstrerror(errno));
|
||||
return (pid_t) -1;
|
||||
|
|
@ -177,7 +177,7 @@ int pa_pid_file_create(void) {
|
|||
snprintf(t, sizeof(t), "%lu\n", (unsigned long) getpid());
|
||||
l = strlen(t);
|
||||
|
||||
if (pa_loop_write(fd, t, l) != (ssize_t) l) {
|
||||
if (pa_loop_write(fd, t, l, NULL) != (ssize_t) l) {
|
||||
pa_log(__FILE__": failed to write PID file.");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ static int random_proper(void *ret_data, size_t length) {
|
|||
|
||||
if ((fd = open(*device, O_RDONLY)) >= 0) {
|
||||
|
||||
if ((r = pa_loop_read(fd, ret_data, length)) < 0 || (size_t) r != length)
|
||||
if ((r = pa_loop_read(fd, ret_data, length, NULL)) < 0 || (size_t) r != length)
|
||||
ret = -1;
|
||||
|
||||
close(fd);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue