From 8d8d32f4d058d5f4723e8ed714ff36937f9fa6fa Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sat, 11 Jun 2016 18:50:40 +0200 Subject: [PATCH 1/2] Problem: Theoretical overflow when polling more than INT_MAX handles. Solution: Always use fd_t when accessing the pollset. --- src/poll.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/poll.cpp b/src/poll.cpp index 23affbab..59eb309d 100644 --- a/src/poll.cpp +++ b/src/poll.cpp @@ -94,25 +94,25 @@ void zmq::poll_t::rm_fd (handle_t handle_) void zmq::poll_t::set_pollin (handle_t handle_) { - int index = fd_table [handle_].index; + fd_t index = fd_table [handle_].index; pollset [index].events |= POLLIN; } void zmq::poll_t::reset_pollin (handle_t handle_) { - int index = fd_table [handle_].index; + fd_t index = fd_table [handle_].index; pollset [index].events &= ~((short) POLLIN); } void zmq::poll_t::set_pollout (handle_t handle_) { - int index = fd_table [handle_].index; + fd_t index = fd_table [handle_].index; pollset [index].events |= POLLOUT; } void zmq::poll_t::reset_pollout (handle_t handle_) { - int index = fd_table [handle_].index; + fd_t index = fd_table [handle_].index; pollset [index].events &= ~((short) POLLOUT); } From 7a6ff07a0123a3373fdd906ff489264509370a61 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sat, 11 Jun 2016 19:14:25 +0200 Subject: [PATCH 2/2] Problem: Windows performance is not optimal due to select(). Solution: Provide poll() for Windows as well. This is a build option that defaults to off as the resulting binary will only run on Windows Vista or newer. This is not tested with alternative Winsock service providers like VMCI, but the documentation for WSAPoll does not mention limitations. On my local machine, throughput improves by ~10 % (20 simultaneous remote_thr workes to one local_thr, 10 byte messages), while latency improves by ~30 % (measured with remote/local_lat). --- builds/msvc/vs2015/libzmq/libzmq.props | 5 ++++- builds/msvc/vs2015/libzmq/libzmq.xml | 5 +++++ src/poll.cpp | 2 ++ src/poll.hpp | 2 ++ src/proxy.cpp | 2 +- src/signaler.cpp | 2 ++ src/socket_poller.hpp | 2 +- src/windows.hpp | 4 ++++ src/zmq.cpp | 2 +- 9 files changed, 22 insertions(+), 4 deletions(-) diff --git a/builds/msvc/vs2015/libzmq/libzmq.props b/builds/msvc/vs2015/libzmq/libzmq.props index 5c98430b..d77bdff6 100644 --- a/builds/msvc/vs2015/libzmq/libzmq.props +++ b/builds/msvc/vs2015/libzmq/libzmq.props @@ -21,13 +21,15 @@ false Use precompiled.hpp - _CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;FD_SETSIZE=16384;WIN32_LEAN_AND_MEAN;ZMQ_USE_SELECT;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;FD_SETSIZE=16384;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) ZMQ_USE_TWEETNACL;%(PreprocessorDefinitions) ZMQ_USE_LIBSODIUM;%(PreprocessorDefinitions) ZMQ_HAVE_CURVE;%(PreprocessorDefinitions) ZMQ_HAVE_OPENPGM;%(PreprocessorDefinitions) HAVE_LIBGSSAPI_KRB5;%(PreprocessorDefinitions) ZMQ_BUILD_DRAFT_API;%(PreprocessorDefinitions) + ZMQ_USE_POLL;%(PreprocessorDefinitions) + ZMQ_USE_SELECT;%(PreprocessorDefinitions) ZMQ_STATIC;%(PreprocessorDefinitions) DLL_EXPORT;%(PreprocessorDefinitions) @@ -64,6 +66,7 @@ + diff --git a/builds/msvc/vs2015/libzmq/libzmq.xml b/builds/msvc/vs2015/libzmq/libzmq.xml index b9887ddc..db7dfe03 100644 --- a/builds/msvc/vs2015/libzmq/libzmq.xml +++ b/builds/msvc/vs2015/libzmq/libzmq.xml @@ -7,6 +7,7 @@ + @@ -31,5 +32,9 @@ + + + + \ No newline at end of file diff --git a/src/poll.cpp b/src/poll.cpp index 59eb309d..1f9163cf 100644 --- a/src/poll.cpp +++ b/src/poll.cpp @@ -32,8 +32,10 @@ #if defined ZMQ_USE_POLL #include +#if !defined ZMQ_HAVE_WINDOWS #include #include +#endif #include #include "poll.hpp" diff --git a/src/poll.hpp b/src/poll.hpp index bc0466fe..84818055 100644 --- a/src/poll.hpp +++ b/src/poll.hpp @@ -34,7 +34,9 @@ #include "poller.hpp" #if defined ZMQ_USE_POLL +#if !defined ZMQ_HAVE_WINDOWS #include +#endif #include #include diff --git a/src/proxy.cpp b/src/proxy.cpp index df970c73..8c626af8 100644 --- a/src/proxy.cpp +++ b/src/proxy.cpp @@ -37,7 +37,7 @@ // definition of pollfd structure (AIX uses 'reqevents' and 'retnevents' // instead of 'events' and 'revents' and defines macros to map from POSIX-y // names to AIX-specific names). -#if defined ZMQ_POLL_BASED_ON_POLL +#if defined ZMQ_POLL_BASED_ON_POLL && !defined ZMQ_HAVE_WINDOWS #include #endif diff --git a/src/signaler.cpp b/src/signaler.cpp index 6c7f9e92..eb84d61c 100644 --- a/src/signaler.cpp +++ b/src/signaler.cpp @@ -35,7 +35,9 @@ // instead of 'events' and 'revents' and defines macros to map from POSIX-y // names to AIX-specific names). #if defined ZMQ_POLL_BASED_ON_POLL +#if !defined ZMQ_HAVE_WINDOWS #include +#endif #elif defined ZMQ_POLL_BASED_ON_SELECT #if defined ZMQ_HAVE_WINDOWS #elif defined ZMQ_HAVE_HPUX diff --git a/src/socket_poller.hpp b/src/socket_poller.hpp index 33b24625..04db836f 100644 --- a/src/socket_poller.hpp +++ b/src/socket_poller.hpp @@ -32,7 +32,7 @@ #include "poller.hpp" -#if defined ZMQ_POLL_BASED_ON_POLL +#if defined ZMQ_POLL_BASED_ON_POLL && !defined ZMQ_HAVE_WINDOWS #include #endif diff --git a/src/windows.hpp b/src/windows.hpp index 1100c5a7..c344f90b 100644 --- a/src/windows.hpp +++ b/src/windows.hpp @@ -79,6 +79,10 @@ struct tcp_keepalive { #include #endif +#if ZMQ_USE_POLL +static inline int poll(struct pollfd *pfd, unsigned long nfds, int timeout) { return WSAPoll(pfd, nfds, timeout); } +#endif + // In MinGW environment AI_NUMERICSERV is not defined. #ifndef AI_NUMERICSERV #define AI_NUMERICSERV 0x0400 diff --git a/src/zmq.cpp b/src/zmq.cpp index 8396f351..d6f58db1 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -36,7 +36,7 @@ // definition of pollfd structure (AIX uses 'reqevents' and 'retnevents' // instead of 'events' and 'revents' and defines macros to map from POSIX-y // names to AIX-specific names). -#if defined ZMQ_POLL_BASED_ON_POLL +#if defined ZMQ_POLL_BASED_ON_POLL && !defined ZMQ_HAVE_WINDOWS #include #endif