summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Zhakov <ivan@apache.org>2017-08-17 15:56:48 +0000
committerIvan Zhakov <ivan@apache.org>2017-08-17 15:56:48 +0000
commit3c5e1eebb67413173df4c29b5bd539e231cb9af2 (patch)
tree119f8d621262a9b7feb7ebc390412c72bdffc6d1
parentdc89f9ac8bc7ce3f1adc2de042725b4e800f2ece (diff)
downloadapr-3c5e1eebb67413173df4c29b5bd539e231cb9af2.tar.gz
apr_socket_listen(): Allow larger backlog queue lengths on Windows 8+.
Starting with Windows 8, the socket listen() function accepts a special SOMAXCONN_HINT(N) argument that allows making the backlog queue length larger than the otherwise predefined limit of around 200: https://msdn.microsoft.com/en-us/library/windows/desktop/ms739168 https://blogs.msdn.microsoft.com/winsdk/2015/06/01/winsocks-listen-backlog-offers-more-flexibility-in-windows-8/ Having a larger listen backlog can be used for certain high performance applications that need to handle lots of incoming connections. One example would be the httpd server with it's "ListenBacklog" directive where setting it to a larger value currently allows serving more concurrent connections on Windows with mpm_winnt. * include/arch/win32/apr_arch_misc.h (enum apr_oslevel_e): Add APR_WIN_8. * misc/win32/misc.c (apr_get_oslevel): Determine whether we are running on Windows 7 or on Windows 8+. * network_io/win32/sockets.c (SOMAXCONN_HINT): Define this macro in case we are building against an older version of Windows SDK. (apr_socket_listen): Use SOMAXCONN_HINT() for the backlog queue length if it's supported by the Windows version we are running on. Patch by: Evgeny Kotkov <evgeny.kotkov {at} visualsvn.com> git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1805309 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES3
-rw-r--r--include/arch/win32/apr_arch_misc.h3
-rw-r--r--misc/win32/misc.c4
-rw-r--r--network_io/win32/sockets.c23
4 files changed, 30 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index c38fd0e76..a0823b77f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -129,6 +129,9 @@ Changes for APR 2.0.0
*) Merge APR-util into APR. [various]
+ *) apr_socket_listen: Allow larger listen backlog values on Windows 8+.
+ [Evgeny Kotkov <evgeny.kotkov visualsvn.com>]
+
Changes for APR and APR-util 1.6.x and later:
*) http://svn.apache.org/viewvc/apr/apr/branches/1.6.x/CHANGES?view=markup
diff --git a/include/arch/win32/apr_arch_misc.h b/include/arch/win32/apr_arch_misc.h
index b2fb98b07..2ee562ec3 100644
--- a/include/arch/win32/apr_arch_misc.h
+++ b/include/arch/win32/apr_arch_misc.h
@@ -105,7 +105,8 @@ typedef enum {
APR_WIN_XP_SP2 = 62,
APR_WIN_2003 = 70,
APR_WIN_VISTA = 80,
- APR_WIN_7 = 90
+ APR_WIN_7 = 90,
+ APR_WIN_8 = 100
} apr_oslevel_e;
extern APR_DECLARE_DATA apr_oslevel_e apr_os_level;
diff --git a/misc/win32/misc.c b/misc/win32/misc.c
index c4c5a4473..337739ca1 100644
--- a/misc/win32/misc.c
+++ b/misc/win32/misc.c
@@ -99,8 +99,10 @@ apr_status_t apr_get_oslevel(apr_oslevel_e *level)
else if (oslev.dwMajorVersion == 6) {
if (oslev.dwMinorVersion == 0)
apr_os_level = APR_WIN_VISTA;
- else
+ else if (oslev.dwMinorVersion == 1)
apr_os_level = APR_WIN_7;
+ else
+ apr_os_level = APR_WIN_8;
}
else {
apr_os_level = APR_WIN_XP;
diff --git a/network_io/win32/sockets.c b/network_io/win32/sockets.c
index be7ddcbde..9c30f70eb 100644
--- a/network_io/win32/sockets.c
+++ b/network_io/win32/sockets.c
@@ -24,6 +24,13 @@
#include "apr_arch_inherit.h"
#include "apr_arch_misc.h"
+/* Borrow the definition of SOMAXCONN_HINT() from Windows SDK 8,
+ * in case the SDK we are building against doesn't have it.
+ */
+#ifndef SOMAXCONN_HINT
+#define SOMAXCONN_HINT(b) (-(b))
+#endif
+
static char generic_inaddr_any[16] = {0}; /* big enough for IPv4 or IPv6 */
static apr_status_t socket_cleanup(void *sock)
@@ -223,7 +230,21 @@ APR_DECLARE(apr_status_t) apr_socket_bind(apr_socket_t *sock,
APR_DECLARE(apr_status_t) apr_socket_listen(apr_socket_t *sock,
apr_int32_t backlog)
{
- if (listen(sock->socketdes, backlog) == SOCKET_ERROR)
+ int backlog_val;
+
+ if (apr_os_level >= APR_WIN_8) {
+ /* Starting from Windows 8, listen() accepts a special SOMAXCONN_HINT()
+ * arg that allows setting the listen backlog value to a larger
+ * value than the predefined Winsock 2 limit (several hundred).
+ * https://blogs.msdn.microsoft.com/winsdk/2015/06/01/winsocks-listen-backlog-offers-more-flexibility-in-windows-8/
+ */
+ backlog_val = SOMAXCONN_HINT(backlog);
+ }
+ else {
+ backlog_val = backlog;
+ }
+
+ if (listen(sock->socketdes, backlog_val) == SOCKET_ERROR)
return apr_get_netos_error();
else
return APR_SUCCESS;