Skip to content

Commit

Permalink
apr_socket_listen(): Allow larger backlog queue lengths on Windows 8+.
Browse files Browse the repository at this point in the history
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>


git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1805309 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Ivan Zhakov committed Aug 17, 2017
1 parent 1116d61 commit 9c527d6
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion include/arch/win32/apr_arch_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion misc/win32/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 22 additions & 1 deletion network_io/win32/sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 9c527d6

Please sign in to comment.