utils: Wrap socket() and pipe() to reduce syscalls

Some platforms provide an implementation of socket() and pipe2() that allow the
caller to specify that the resulting file descriptors should be non-blocking.

Using these allows us to potentially elide 3 calls into 1 by avoiding extraneous
calls to fcntl() to set the O_NONBLOCK flag afterwards.

In passing, change ast_alertpipe_init() to use pipe2() directly instead of the
wrapper if it is available.

Change-Id: I3ebe654fb549587537161506c6c950f4ab298bb0
This commit is contained in:
Sean Bright
2018-12-07 07:57:48 -05:00
parent 1657508ddd
commit 8a18fb81c1
6 changed files with 175 additions and 8 deletions

View File

@@ -2750,6 +2750,42 @@ int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op,
return 0;
}
#ifndef HAVE_SOCK_NONBLOCK
int ast_socket_nonblock(int domain, int type, int protocol)
{
int s = socket(domain, type, protocol);
if (s < 0) {
return -1;
}
if (ast_fd_set_flags(s, O_NONBLOCK)) {
close(s);
return -1;
}
return s;
}
#endif
#ifndef HAVE_PIPE2
int ast_pipe_nonblock(int filedes[2])
{
int p = pipe(filedes);
if (p < 0) {
return -1;
}
if (ast_fd_set_flags(filedes[0], O_NONBLOCK)
|| ast_fd_set_flags(filedes[1], O_NONBLOCK)) {
close(filedes[0]);
close(filedes[1]);
return -1;
}
return 0;
}
#endif
/*!
* \brief A thread local indicating whether the current thread is a user interface.
*/