socket: add support for socket() flags
On start, check if the SOCK_CLOEXEC and SOCK_NONBLOCK flags are supported in the socket() call and use them instead of fcntl() in order to reduce the number of system calls required to send a client request.
This commit is contained in:
parent
4d26cfc92b
commit
27fd751915
1 changed files with 47 additions and 3 deletions
50
socket.c
50
socket.c
|
@ -82,6 +82,9 @@ struct MessageHeader {
|
||||||
|
|
||||||
static int initialised;
|
static int initialised;
|
||||||
|
|
||||||
|
/* Flags supported by socket() */
|
||||||
|
static int socket_flags;
|
||||||
|
|
||||||
/* Arrays of Message and MessageHeader */
|
/* Arrays of Message and MessageHeader */
|
||||||
static ARR_Instance recv_messages;
|
static ARR_Instance recv_messages;
|
||||||
static ARR_Instance recv_headers;
|
static ARR_Instance recv_headers;
|
||||||
|
@ -140,12 +143,35 @@ domain_to_string(int domain)
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_socket_flag(int sock_flag, int fd_flag, int fs_flag)
|
||||||
|
{
|
||||||
|
int sock_fd, fd_flags, fs_flags;
|
||||||
|
|
||||||
|
sock_fd = socket(AF_INET, SOCK_DGRAM | sock_flag, 0);
|
||||||
|
if (sock_fd < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fd_flags = fcntl(sock_fd, F_GETFD);
|
||||||
|
fs_flags = fcntl(sock_fd, F_GETFL);
|
||||||
|
|
||||||
|
close(sock_fd);
|
||||||
|
|
||||||
|
if (fd_flags == -1 || (fd_flags & fd_flag) != fd_flag ||
|
||||||
|
fs_flags == -1 || (fs_flags & fs_flag) != fs_flag)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
open_socket(int domain, int type, int flags)
|
open_socket(int domain, int type, int flags)
|
||||||
{
|
{
|
||||||
int sock_fd;
|
int sock_fd;
|
||||||
|
|
||||||
sock_fd = socket(domain, type, 0);
|
sock_fd = socket(domain, type | socket_flags, 0);
|
||||||
|
|
||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
DEBUG_LOG("Could not open %s socket : %s",
|
DEBUG_LOG("Could not open %s socket : %s",
|
||||||
|
@ -154,14 +180,22 @@ open_socket(int domain, int type, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close the socket automatically on exec */
|
/* Close the socket automatically on exec */
|
||||||
if (!UTI_FdSetCloexec(sock_fd)) {
|
if (
|
||||||
|
#ifdef SOCK_CLOEXEC
|
||||||
|
(socket_flags & SOCK_CLOEXEC) == 0 &&
|
||||||
|
#endif
|
||||||
|
!UTI_FdSetCloexec(sock_fd)) {
|
||||||
DEBUG_LOG("Could not set O_CLOEXEC : %s", strerror(errno));
|
DEBUG_LOG("Could not set O_CLOEXEC : %s", strerror(errno));
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
return INVALID_SOCK_FD;
|
return INVALID_SOCK_FD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable non-blocking mode */
|
/* Enable non-blocking mode */
|
||||||
if (fcntl(sock_fd, F_SETFL, O_NONBLOCK)) {
|
if (
|
||||||
|
#ifdef SOCK_NONBLOCK
|
||||||
|
(socket_flags & SOCK_NONBLOCK) == 0 &&
|
||||||
|
#endif
|
||||||
|
fcntl(sock_fd, F_SETFL, O_NONBLOCK)) {
|
||||||
DEBUG_LOG("Could not set O_NONBLOCK : %s", strerror(errno));
|
DEBUG_LOG("Could not set O_NONBLOCK : %s", strerror(errno));
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
return INVALID_SOCK_FD;
|
return INVALID_SOCK_FD;
|
||||||
|
@ -943,6 +977,16 @@ SCK_Initialise(void)
|
||||||
|
|
||||||
priv_bind_function = NULL;
|
priv_bind_function = NULL;
|
||||||
|
|
||||||
|
socket_flags = 0;
|
||||||
|
#ifdef SOCK_CLOEXEC
|
||||||
|
if (check_socket_flag(SOCK_CLOEXEC, FD_CLOEXEC, 0))
|
||||||
|
socket_flags |= SOCK_CLOEXEC;
|
||||||
|
#endif
|
||||||
|
#ifdef SOCK_NONBLOCK
|
||||||
|
if (check_socket_flag(SOCK_NONBLOCK, 0, O_NONBLOCK))
|
||||||
|
socket_flags |= SOCK_NONBLOCK;
|
||||||
|
#endif
|
||||||
|
|
||||||
initialised = 1;
|
initialised = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue