Problem: API poller cannot be set independently from I/O thread poller, poll I/O thread poller broken on Windows

Solution: change platform definitions to separate API poller from I/O thread poller, disallow configuring poll I/O thread poller on Windows
This commit is contained in:
Simon Giesecke 2018-05-22 15:57:20 +02:00
parent ee85957dc4
commit d326434b37
17 changed files with 110 additions and 68 deletions

View File

@ -94,7 +94,10 @@ if (WITH_MILITANT)
add_definitions(-DZMQ_ACT_MILITANT)
endif()
set (POLLER "" CACHE STRING "Choose polling system. valid values are
set (API_POLLER "" CACHE STRING "Choose polling system for zmq_poll(er)_*. valid values are
poll or select [default=poll unless POLLER=select]")
set (POLLER "" CACHE STRING "Choose polling system for I/O threads. valid values are
kqueue, epoll, devpoll, pollset, poll or select [default=autodetect]")
include (CheckFunctionExists)
@ -117,7 +120,7 @@ if (POLLER STREQUAL "")
set (POLLER "epoll")
check_function_exists (epoll_create1 HAVE_EPOLL_CLOEXEC)
if (HAVE_EPOLL_CLOEXEC)
set (ZMQ_USE_EPOLL_CLOEXEC 1)
set (ZMQ_IOTHREAD_POLLER_USE_EPOLL_CLOEXEC 1)
endif ()
endif ()
endif ()
@ -172,13 +175,25 @@ if (POLLER STREQUAL "kqueue"
OR POLLER STREQUAL "pollset"
OR POLLER STREQUAL "poll"
OR POLLER STREQUAL "select")
message (STATUS "Detected ${POLLER} polling method")
message (STATUS "Using polling method in I/O threads: ${POLLER}")
string (TOUPPER ${POLLER} UPPER_POLLER)
set (ZMQ_USE_${UPPER_POLLER} 1)
set (ZMQ_IOTHREAD_POLLER_USE_${UPPER_POLLER} 1)
else ()
message (FATAL_ERROR "Invalid polling method")
endif ()
if (API_POLLER STREQUAL "")
if (POLLER STREQUAL "select")
set (API_POLLER "select")
else()
set (API_POLLER "poll")
endif()
endif()
message (STATUS "Using polling method in zmq_poll(er)_* API: ${API_POLLER}")
string (TOUPPER ${API_POLLER} UPPER_API_POLLER)
set (ZMQ_POLL_BASED_ON_${UPPER_API_POLLER} 1)
include (TestZMQVersion)
if (NOT CMAKE_CROSSCOMPILING)
include (ZMQSourceRunChecks)

View File

@ -1052,7 +1052,12 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
# Allow user to override poller autodetection
AC_ARG_WITH([poller],
[AS_HELP_STRING([--with-poller],
[choose polling system manually. Valid values are 'kqueue', 'epoll', 'devpoll', 'pollset', 'poll', 'select', or 'auto'. [default=auto]])])
[choose I/O thread polling system manually. Valid values are 'kqueue', 'epoll', 'devpoll', 'pollset', 'poll', 'select', or 'auto'. [default=auto]])])
# Allow user to override poller autodetection
AC_ARG_WITH([api_poller],
[AS_HELP_STRING([--with-api-poller],
[choose zmq_poll(er)_* API polling system manually. Valid values are 'poll', 'select', or 'auto'. [default=auto]])])
if test "x$with_poller" == "x"; then
pollers=auto
@ -1065,14 +1070,14 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
fi
# try to find suitable polling system. the order of testing is:
AC_MSG_NOTICE([Choosing polling system from '$pollers'...])
AC_MSG_NOTICE([Choosing I/O thread polling system from '$pollers'...])
poller_found=0
for poller in $pollers; do
case "$poller" in
kqueue)
LIBZMQ_CHECK_POLLER_KQUEUE([
AC_MSG_NOTICE([Using 'kqueue' polling system])
AC_DEFINE(ZMQ_USE_KQUEUE, 1, [Use 'kqueue' polling system])
AC_MSG_NOTICE([Using 'kqueue' I/O thread polling system])
AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_KQUEUE, 1, [Use 'kqueue' I/O thread polling system])
poller_found=1
])
;;
@ -1084,17 +1089,17 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
# that ZMQ has from Linux systems. Unless you undertake
# to fix the integration, do not disable this exception
# and use select() or poll() on Solarish OSes for now.
AC_MSG_NOTICE([NOT using 'epoll' polling system on '$host_os']) ;;
AC_MSG_NOTICE([NOT using 'epoll' I/O thread polling system on '$host_os']) ;;
*)
LIBZMQ_CHECK_POLLER_EPOLL_CLOEXEC([
AC_MSG_NOTICE([Using 'epoll' polling system with CLOEXEC])
AC_DEFINE(ZMQ_USE_EPOLL, 1, [Use 'epoll' polling system])
AC_DEFINE(ZMQ_USE_EPOLL_CLOEXEC, 1, [Use 'epoll' polling system with CLOEXEC])
AC_MSG_NOTICE([Using 'epoll' I/O thread polling system with CLOEXEC])
AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_EPOLL, 1, [Use 'epoll' I/O thread polling system])
AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_EPOLL_CLOEXEC, 1, [Use 'epoll' I/O thread polling system with CLOEXEC])
poller_found=1
],[
LIBZMQ_CHECK_POLLER_EPOLL([
AC_MSG_NOTICE([Using 'epoll' polling system with CLOEXEC])
AC_DEFINE(ZMQ_USE_EPOLL, 1, [Use 'epoll' polling system])
AC_MSG_NOTICE([Using 'epoll' I/O thread polling system with CLOEXEC])
AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_EPOLL, 1, [Use 'epoll' I/O thread polling system])
poller_found=1
])
])
@ -1103,29 +1108,29 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
;;
devpoll)
LIBZMQ_CHECK_POLLER_DEVPOLL([
AC_MSG_NOTICE([Using 'devpoll' polling system])
AC_DEFINE(ZMQ_USE_DEVPOLL, 1, [Use 'devpoll' polling system])
AC_MSG_NOTICE([Using 'devpoll' I/O thread polling system])
AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_DEVPOLL, 1, [Use 'devpoll' I/O thread polling system])
poller_found=1
])
;;
pollset)
LIBZMQ_CHECK_POLLER_POLLSET([
AC_MSG_NOTICE([Using 'pollset' polling system])
AC_DEFINE(ZMQ_USE_POLLSET, 1, [Use 'pollset' polling system])
AC_MSG_NOTICE([Using 'pollset' I/O thread polling system])
AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_POLLSET, 1, [Use 'pollset' I/O thread polling system])
poller_found=1
])
;;
poll)
LIBZMQ_CHECK_POLLER_POLL([
AC_MSG_NOTICE([Using 'poll' polling system])
AC_DEFINE(ZMQ_USE_POLL, 1, [Use 'poll' polling system])
AC_MSG_NOTICE([Using 'poll' I/O thread polling system])
AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_POLL, 1, [Use 'poll' I/O thread polling system])
poller_found=1
])
;;
select)
LIBZMQ_CHECK_POLLER_SELECT([
AC_MSG_NOTICE([Using 'select' polling system])
AC_DEFINE(ZMQ_USE_SELECT, 1, [Use 'select' polling system])
AC_MSG_NOTICE([Using 'select' I/O thread polling system])
AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_SELECT, 1, [Use 'select' I/O thread polling system])
poller_found=1
])
;;
@ -1135,4 +1140,25 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
if test $poller_found -eq 0; then
AC_MSG_ERROR([None of '$pollers' are valid pollers on this platform])
fi
if test "x$with_api_poller" == "x"; then
with_api_poller=auto
fi
if test "x$with_api_poller" == "xauto"; then
if test $poller == "select"; then
api_poller=select
else
api_poller=poll
fi
else
api_poller=$with_api_poller
fi
if test "$api_poller" == "select"; then
AC_MSG_NOTICE([Using 'select' zmq_poll(er)_* API polling system])
AC_DEFINE(ZMQ_POLL_BASED_ON_SELECT, 1, [Use 'select' zmq_poll(er)_* API polling system])
elif test "$api_poller" == "poll"; then
AC_MSG_NOTICE([Using 'poll' zmq_poll(er)_* API polling system])
AC_DEFINE(ZMQ_POLL_BASED_ON_POLL, 1, [Use 'poll' zmq_poll(er)_* API polling system])
else
AC_MSG_ERROR([Invalid API poller '$api_poller' specified])
fi
}])

View File

@ -1,12 +1,15 @@
#ifndef __ZMQ_PLATFORM_HPP_INCLUDED__
#define __ZMQ_PLATFORM_HPP_INCLUDED__
#cmakedefine ZMQ_USE_KQUEUE
#cmakedefine ZMQ_USE_EPOLL
#cmakedefine ZMQ_USE_EPOLL_CLOEXEC
#cmakedefine ZMQ_USE_DEVPOLL
#cmakedefine ZMQ_USE_POLL
#cmakedefine ZMQ_USE_SELECT
#cmakedefine ZMQ_IOTHREAD_POLLER_USE_KQUEUE
#cmakedefine ZMQ_IOTHREAD_POLLER_USE_EPOLL
#cmakedefine ZMQ_IOTHREAD_POLLER_USE_EPOLL_CLOEXEC
#cmakedefine ZMQ_IOTHREAD_POLLER_USE_DEVPOLL
#cmakedefine ZMQ_IOTHREAD_POLLER_USE_POLL
#cmakedefine ZMQ_IOTHREAD_POLLER_USE_SELECT
#cmakedefine ZMQ_POLL_BASED_ON_SELECT
#cmakedefine ZMQ_POLL_BASED_ON_POLL
#cmakedefine ZMQ_FORCE_MUTEXES

View File

@ -29,7 +29,7 @@
#include "precompiled.hpp"
#include "devpoll.hpp"
#if defined ZMQ_USE_DEVPOLL
#if defined ZMQ_IOTHREAD_POLLER_USE_DEVPOLL
#include <sys/devpoll.h>
#include <sys/time.h>

View File

@ -32,7 +32,7 @@
// poller.hpp decides which polling mechanism to use.
#include "poller.hpp"
#if defined ZMQ_USE_DEVPOLL
#if defined ZMQ_IOTHREAD_POLLER_USE_DEVPOLL
#include <vector>

View File

@ -29,7 +29,7 @@
#include "precompiled.hpp"
#include "epoll.hpp"
#if defined ZMQ_USE_EPOLL
#if defined ZMQ_IOTHREAD_POLLER_USE_EPOLL
#include <sys/epoll.h>
#include <stdlib.h>

View File

@ -32,7 +32,7 @@
// poller.hpp decides which polling mechanism to use.
#include "poller.hpp"
#if defined ZMQ_USE_EPOLL
#if defined ZMQ_IOTHREAD_POLLER_USE_EPOLL
#include <vector>
#include <sys/epoll.h>

View File

@ -29,7 +29,7 @@
#include "precompiled.hpp"
#include "kqueue.hpp"
#if defined ZMQ_USE_KQUEUE
#if defined ZMQ_IOTHREAD_POLLER_USE_KQUEUE
#include <sys/time.h>
#include <sys/types.h>

View File

@ -32,7 +32,7 @@
// poller.hpp decides which polling mechanism to use.
#include "poller.hpp"
#if defined ZMQ_USE_KQUEUE
#if defined ZMQ_IOTHREAD_POLLER_USE_KQUEUE
#include <vector>
#include <unistd.h>

View File

@ -29,13 +29,11 @@
#include "precompiled.hpp"
#include "poll.hpp"
#if defined ZMQ_USE_POLL
#if defined ZMQ_IOTHREAD_POLLER_USE_POLL
#include <sys/types.h>
#if !defined ZMQ_HAVE_WINDOWS
#include <sys/time.h>
#include <poll.h>
#endif
#include <algorithm>
#include "poll.hpp"
@ -43,10 +41,6 @@
#include "config.hpp"
#include "i_poll_events.hpp"
#ifdef ZMQ_HAVE_WINDOWS
typedef unsigned long nfds_t;
#endif
zmq::poll_t::poll_t (const zmq::thread_ctx_t &ctx_) :
worker_poller_base_t (ctx_),
retired (false)
@ -161,14 +155,10 @@ void zmq::poll_t::loop ()
// Wait for events.
int rc = poll (&pollset[0], static_cast<nfds_t> (pollset.size ()),
timeout ? timeout : -1);
#ifdef ZMQ_HAVE_WINDOWS
wsa_assert (rc != SOCKET_ERROR);
#else
if (rc == -1) {
errno_assert (errno == EINTR);
continue;
}
#endif
// If there are no events (i.e. it's a timeout) there's no point
// in checking the pollset.

View File

@ -32,11 +32,15 @@
// poller.hpp decides which polling mechanism to use.
#include "poller.hpp"
#if defined ZMQ_USE_POLL
#if defined ZMQ_IOTHREAD_POLLER_USE_POLL
#if !defined ZMQ_HAVE_WINDOWS
#include <poll.h>
#if defined ZMQ_HAVE_WINDOWS
#error \
"poll is broken on Windows for the purpose of the I/O thread poller, use select instead; "\
"see https://github.com/zeromq/libzmq/issues/3107"
#endif
#include <poll.h>
#include <stddef.h>
#include <vector>

View File

@ -30,35 +30,39 @@
#ifndef __ZMQ_POLLER_HPP_INCLUDED__
#define __ZMQ_POLLER_HPP_INCLUDED__
#if defined ZMQ_USE_KQUEUE + defined ZMQ_USE_EPOLL + defined ZMQ_USE_DEVPOLL \
+ defined ZMQ_USE_POLLSET + defined ZMQ_USE_POLL + defined ZMQ_USE_SELECT \
#if defined ZMQ_IOTHREAD_POLLER_USE_KQUEUE \
+ defined ZMQ_IOTHREAD_POLLER_USE_EPOLL \
+ defined ZMQ_IOTHREAD_POLLER_USE_DEVPOLL \
+ defined ZMQ_IOTHREAD_POLLER_USE_POLLSET \
+ defined ZMQ_IOTHREAD_POLLER_POLL \
+ defined ZMQ_IOTHREAD_POLLER_USE_SELECT \
> 1
#error More than one of the ZMQ_USE_* macros defined
#error More than one of the ZMQ_IOTHREAD_POLLER_USE_* macros defined
#endif
#if defined ZMQ_USE_KQUEUE
#if defined ZMQ_IOTHREAD_POLLER_USE_KQUEUE
#include "kqueue.hpp"
#elif defined ZMQ_USE_EPOLL
#elif defined ZMQ_IOTHREAD_POLLER_USE_EPOLL
#include "epoll.hpp"
#elif defined ZMQ_USE_DEVPOLL
#elif defined ZMQ_IOTHREAD_POLLER_USE_DEVPOLL
#include "devpoll.hpp"
#elif defined ZMQ_USE_POLLSET
#elif defined ZMQ_IOTHREAD_POLLER_USE_POLLSET
#include "pollset.hpp"
#elif defined ZMQ_USE_POLL
#elif defined ZMQ_IOTHREAD_POLLER_USE_POLL
#include "poll.hpp"
#elif defined ZMQ_USE_SELECT
#elif defined ZMQ_IOTHREAD_POLLER_USE_SELECT
#include "select.hpp"
#elif defined ZMQ_HAVE_GNU
#define ZMQ_USE_POLL
#define ZMQ_IOTHREAD_POLLER_USE_POLL
#include "poll.hpp"
#else
#error None of the ZMQ_USE_* macros defined
#error None of the ZMQ_IOTHREAD_POLLER_USE_* macros defined
#endif
#if defined ZMQ_USE_SELECT
#define ZMQ_POLL_BASED_ON_SELECT
#else
#define ZMQ_POLL_BASED_ON_POLL
#if (defined ZMQ_POLL_BASED_ON_SELECT + defined ZMQ_POLL_BASED_ON_POLL) > 1
#error More than one of the ZMQ_POLL_BASED_ON_* macros defined
#elif (defined ZMQ_POLL_BASED_ON_SELECT + defined ZMQ_POLL_BASED_ON_POLL) == 0
#error None of the ZMQ_POLL_BASED_ON_* macros defined
#endif
#endif

View File

@ -29,7 +29,7 @@
#include "precompiled.hpp"
#include "pollset.hpp"
#if defined ZMQ_USE_POLLSET
#if defined ZMQ_IOTHREAD_POLLER_USE_POLLSET
#include <stdlib.h>
#include <string.h>

View File

@ -32,7 +32,7 @@
// poller.hpp decides which polling mechanism to use.
#include "poller.hpp"
#if defined ZMQ_USE_POLLSET
#if defined ZMQ_IOTHREAD_POLLER_USE_POLLSET
#include <sys/poll.h>
#include <sys/pollset.h>

View File

@ -29,7 +29,7 @@
#include "precompiled.hpp"
#include "select.hpp"
#if defined ZMQ_USE_SELECT
#if defined ZMQ_IOTHREAD_POLLER_USE_SELECT
#if defined ZMQ_HAVE_WINDOWS
#elif defined ZMQ_HAVE_HPUX

View File

@ -32,7 +32,7 @@
// poller.hpp decides which polling mechanism to use.
#include "poller.hpp"
#if defined ZMQ_USE_SELECT
#if defined ZMQ_IOTHREAD_POLLER_USE_SELECT
#include <stddef.h>
#include <vector>

View File

@ -83,7 +83,7 @@ struct tcp_keepalive
#include <process.h>
#endif
#if defined ZMQ_USE_POLL
#if defined ZMQ_IOTHREAD_POLLER_USE_POLL || defined ZMQ_POLL_BASED_ON_POLL
static inline int poll (struct pollfd *pfd, unsigned long nfds, int timeout)
{
return WSAPoll (pfd, nfds, timeout);