diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-01-21 19:53:45 +0000 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-01-21 19:53:45 +0000 |
commit | 1e11762d5fabd80c70e226dd608fc6322de5ce61 (patch) | |
tree | e3229f494b5fe9b2aaef77a39905b84e202c70b4 | |
parent | dcebe56be139a0b4dbc4926c1d95e6dc4972ab67 (diff) | |
download | libmicrohttpd-1e11762d5fabd80c70e226dd608fc6322de5ce61.tar.gz libmicrohttpd-1e11762d5fabd80c70e226dd608fc6322de5ce61.zip |
Reworked code for using accept4(), epoll_create1() and socket() with SOCK_CLOEXEC, SOCK_NONBLOCK and EPOLL_CLOEXEC. On some systems SOCK_CLOEXEC, SOCK_NONBLOCK and EPOLL_CLOEXEC are defined as enum members with the same names so precompiler assume zero value of such macros.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 45 |
2 files changed, 31 insertions, 22 deletions
@@ -1,3 +1,11 @@ | |||
1 | Thu Jan 21 19:35:18 CET 2016 | ||
2 | Fixed old bug with making sockets non-blocking on | ||
3 | various platforms so now sockets are really | ||
4 | non-blocking on all supported platforms. | ||
5 | Reworked and fixed code for using SOCK_CLOEXEC, | ||
6 | SOCK_NONBLOCK and EPOLL_CLOEXEC resulting in | ||
7 | fewer used system calls. -EG | ||
8 | |||
1 | Tue Jan 19 20:59:59 CET 2016 | 9 | Tue Jan 19 20:59:59 CET 2016 |
2 | Cleaned up and optimized with minor fixes code for | 10 | Cleaned up and optimized with minor fixes code for |
3 | making sockets non-blocking non-inheritable. -EG | 11 | making sockets non-blocking non-inheritable. -EG |
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index e313959e..1efcb43b 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -103,18 +103,26 @@ | |||
103 | #endif | 103 | #endif |
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | #ifndef SOCK_CLOEXEC | 106 | #ifdef SOCK_CLOEXEC |
107 | #define SOCK_CLOEXEC 0 | 107 | #define MAYBE_SOCK_CLOEXEC SOCK_CLOEXEC |
108 | #endif | 108 | #else /* ! SOCK_CLOEXEC */ |
109 | #define MAYBE_SOCK_CLOEXEC 0 | ||
110 | #endif /* ! SOCK_CLOEXEC */ | ||
109 | 111 | ||
110 | #ifndef EPOLL_CLOEXEC | 112 | #ifdef HAVE_SOCK_NONBLOCK |
111 | #define EPOLL_CLOEXEC 0 | 113 | #define MAYBE_SOCK_NONBLOCK SOCK_NONBLOCK |
112 | #endif | 114 | #else /* ! HAVE_SOCK_NONBLOCK */ |
115 | #define MAYBE_SOCK_NONBLOCK 0 | ||
116 | #endif /* ! HAVE_SOCK_NONBLOCK */ | ||
113 | 117 | ||
114 | #if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || (SOCK_CLOEXEC+0 != 0)) | 118 | #if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || defined(SOCK_CLOEXEC)) |
115 | #define USE_ACCEPT4 1 | 119 | #define USE_ACCEPT4 1 |
116 | #endif | 120 | #endif |
117 | 121 | ||
122 | #if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC) | ||
123 | #define USE_EPOLL_CREATE1 1 | ||
124 | #endif /* HAVE_EPOLL_CREATE1 && EPOLL_CLOEXEC */ | ||
125 | |||
118 | 126 | ||
119 | /** | 127 | /** |
120 | * Default implementation of the panic function, | 128 | * Default implementation of the panic function, |
@@ -1980,20 +1988,13 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
1980 | socklen_t addrlen; | 1988 | socklen_t addrlen; |
1981 | MHD_socket s; | 1989 | MHD_socket s; |
1982 | MHD_socket fd; | 1990 | MHD_socket fd; |
1983 | #ifdef USE_ACCEPT4 | ||
1984 | #ifdef HAVE_SOCK_NONBLOCK | ||
1985 | static const int nonblock = SOCK_NONBLOCK; | ||
1986 | #else | ||
1987 | static const int nonblock = 0; | ||
1988 | #endif | ||
1989 | #endif /* USE_ACCEPT4 */ | ||
1990 | 1991 | ||
1991 | addrlen = sizeof (addrstorage); | 1992 | addrlen = sizeof (addrstorage); |
1992 | memset (addr, 0, sizeof (addrstorage)); | 1993 | memset (addr, 0, sizeof (addrstorage)); |
1993 | if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd)) | 1994 | if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd)) |
1994 | return MHD_NO; | 1995 | return MHD_NO; |
1995 | #ifdef USE_ACCEPT4 | 1996 | #ifdef USE_ACCEPT4 |
1996 | s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock); | 1997 | s = accept4 (fd, addr, &addrlen, MAYBE_SOCK_CLOEXEC | MAYBE_SOCK_NONBLOCK); |
1997 | #else /* ! USE_ACCEPT4 */ | 1998 | #else /* ! USE_ACCEPT4 */ |
1998 | s = accept (fd, addr, &addrlen); | 1999 | s = accept (fd, addr, &addrlen); |
1999 | #endif /* ! USE_ACCEPT4 */ | 2000 | #endif /* ! USE_ACCEPT4 */ |
@@ -2022,7 +2023,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
2022 | make_nonblocking_noninheritable (daemon, s); | 2023 | make_nonblocking_noninheritable (daemon, s); |
2023 | #elif !defined(HAVE_SOCK_NONBLOCK) | 2024 | #elif !defined(HAVE_SOCK_NONBLOCK) |
2024 | make_nonblocking (daemon, s); | 2025 | make_nonblocking (daemon, s); |
2025 | #elif SOCK_CLOEXEC+0 == 0 | 2026 | #elif !defined(SOCK_CLOEXEC) |
2026 | make_noninheritable (daemon, s); | 2027 | make_noninheritable (daemon, s); |
2027 | #endif | 2028 | #endif |
2028 | #ifdef HAVE_MESSAGES | 2029 | #ifdef HAVE_MESSAGES |
@@ -3564,7 +3565,7 @@ create_listen_socket (struct MHD_Daemon *daemon, | |||
3564 | 3565 | ||
3565 | /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo | 3566 | /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo |
3566 | * implementations do not set ai_socktype, e.g. RHL6.2. */ | 3567 | * implementations do not set ai_socktype, e.g. RHL6.2. */ |
3567 | #if defined(MHD_POSIX_SOCKETS) && SOCK_CLOEXEC+0 != 0 | 3568 | #if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC) |
3568 | fd = socket (domain, type | SOCK_CLOEXEC, protocol); | 3569 | fd = socket (domain, type | SOCK_CLOEXEC, protocol); |
3569 | cloexec_set = MHD_YES; | 3570 | cloexec_set = MHD_YES; |
3570 | #elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) | 3571 | #elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT) |
@@ -3600,11 +3601,11 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) | |||
3600 | { | 3601 | { |
3601 | struct epoll_event event; | 3602 | struct epoll_event event; |
3602 | 3603 | ||
3603 | #ifdef HAVE_EPOLL_CREATE1 | 3604 | #ifdef USE_EPOLL_CREATE1 |
3604 | daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC); | 3605 | daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC); |
3605 | #else /* !HAVE_EPOLL_CREATE1 */ | 3606 | #else /* ! USE_EPOLL_CREATE1 */ |
3606 | daemon->epoll_fd = epoll_create (MAX_EVENTS); | 3607 | daemon->epoll_fd = epoll_create (MAX_EVENTS); |
3607 | #endif /* !HAVE_EPOLL_CREATE1 */ | 3608 | #endif /* ! USE_EPOLL_CREATE1 */ |
3608 | if (-1 == daemon->epoll_fd) | 3609 | if (-1 == daemon->epoll_fd) |
3609 | { | 3610 | { |
3610 | #ifdef HAVE_MESSAGES | 3611 | #ifdef HAVE_MESSAGES |
@@ -3614,10 +3615,10 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) | |||
3614 | #endif | 3615 | #endif |
3615 | return MHD_NO; | 3616 | return MHD_NO; |
3616 | } | 3617 | } |
3617 | #if !defined(HAVE_EPOLL_CREATE1) || EPOLL_CLOEXEC+0 == 0 | 3618 | #if !defined(USE_EPOLL_CREATE1) |
3618 | make_noninheritable (daemon, | 3619 | make_noninheritable (daemon, |
3619 | daemon->epoll_fd); | 3620 | daemon->epoll_fd); |
3620 | #endif /* !HAVE_EPOLL_CREATE1 || !EPOLL_CLOEXEC */ | 3621 | #endif /* ! USE_EPOLL_CREATE1 */ |
3621 | if (MHD_INVALID_SOCKET == daemon->socket_fd) | 3622 | if (MHD_INVALID_SOCKET == daemon->socket_fd) |
3622 | return MHD_YES; /* non-listening daemon */ | 3623 | return MHD_YES; /* non-listening daemon */ |
3623 | event.events = EPOLLIN; | 3624 | event.events = EPOLLIN; |