Hi everyone, 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. The attached patch starts using SOMAXCONN_HINT() in the Win32 implementation of the apr_socket_listen() function if this feature is supported by the underlying version of Windows. The log message is included in the beginning of the patch file. Regards, Evgeny Kotkov
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 (apr_socket_listen): Use SOMAXCONN_HINT() if it's supported by both the SDK we are building against and the Windows version we are running on. Patch by: Evgeny Kotkov <evgeny.kotkov {at} visualsvn.com> Index: include/arch/win32/apr_arch_misc.h =================================================================== --- include/arch/win32/apr_arch_misc.h (revision 1801587) +++ include/arch/win32/apr_arch_misc.h (working copy) @@ -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; Index: misc/win32/misc.c =================================================================== --- misc/win32/misc.c (revision 1801587) +++ misc/win32/misc.c (working copy) @@ -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 if (oslev.dwMinorVersion == 1) + apr_os_level = APR_WIN_7; else - apr_os_level = APR_WIN_7; + apr_os_level = APR_WIN_8; } else { apr_os_level = APR_WIN_XP; Index: network_io/win32/sockets.c =================================================================== --- network_io/win32/sockets.c (revision 1801587) +++ network_io/win32/sockets.c (working copy) @@ -223,7 +223,20 @@ APR_DECLARE(apr_status_t) apr_socket_bind(apr_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 = backlog; + +#ifdef SOMAXCONN_HINT + 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); + } +#endif + + if (listen(sock->socketdes, backlog_val) == SOCKET_ERROR) return apr_get_netos_error(); else return APR_SUCCESS;