0
0
mirror of https://github.com/zeromq/libzmq.git synced 2024-12-27 07:31:03 +08:00

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) add_definitions(-DZMQ_ACT_MILITANT)
endif() 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]") kqueue, epoll, devpoll, pollset, poll or select [default=autodetect]")
include (CheckFunctionExists) include (CheckFunctionExists)
@ -117,7 +120,7 @@ if (POLLER STREQUAL "")
set (POLLER "epoll") set (POLLER "epoll")
check_function_exists (epoll_create1 HAVE_EPOLL_CLOEXEC) check_function_exists (epoll_create1 HAVE_EPOLL_CLOEXEC)
if (HAVE_EPOLL_CLOEXEC) if (HAVE_EPOLL_CLOEXEC)
set (ZMQ_USE_EPOLL_CLOEXEC 1) set (ZMQ_IOTHREAD_POLLER_USE_EPOLL_CLOEXEC 1)
endif () endif ()
endif () endif ()
endif () endif ()
@ -172,13 +175,25 @@ if (POLLER STREQUAL "kqueue"
OR POLLER STREQUAL "pollset" OR POLLER STREQUAL "pollset"
OR POLLER STREQUAL "poll" OR POLLER STREQUAL "poll"
OR POLLER STREQUAL "select") 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) string (TOUPPER ${POLLER} UPPER_POLLER)
set (ZMQ_USE_${UPPER_POLLER} 1) set (ZMQ_IOTHREAD_POLLER_USE_${UPPER_POLLER} 1)
else () else ()
message (FATAL_ERROR "Invalid polling method") message (FATAL_ERROR "Invalid polling method")
endif () 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) include (TestZMQVersion)
if (NOT CMAKE_CROSSCOMPILING) if (NOT CMAKE_CROSSCOMPILING)
include (ZMQSourceRunChecks) include (ZMQSourceRunChecks)

View File

@ -1052,7 +1052,12 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
# Allow user to override poller autodetection # Allow user to override poller autodetection
AC_ARG_WITH([poller], AC_ARG_WITH([poller],
[AS_HELP_STRING([--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 if test "x$with_poller" == "x"; then
pollers=auto pollers=auto
@ -1065,14 +1070,14 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
fi fi
# try to find suitable polling system. the order of testing is: # 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 poller_found=0
for poller in $pollers; do for poller in $pollers; do
case "$poller" in case "$poller" in
kqueue) kqueue)
LIBZMQ_CHECK_POLLER_KQUEUE([ LIBZMQ_CHECK_POLLER_KQUEUE([
AC_MSG_NOTICE([Using 'kqueue' polling system]) AC_MSG_NOTICE([Using 'kqueue' I/O thread polling system])
AC_DEFINE(ZMQ_USE_KQUEUE, 1, [Use 'kqueue' polling system]) AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_KQUEUE, 1, [Use 'kqueue' I/O thread polling system])
poller_found=1 poller_found=1
]) ])
;; ;;
@ -1084,17 +1089,17 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
# that ZMQ has from Linux systems. Unless you undertake # that ZMQ has from Linux systems. Unless you undertake
# to fix the integration, do not disable this exception # to fix the integration, do not disable this exception
# and use select() or poll() on Solarish OSes for now. # 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([ LIBZMQ_CHECK_POLLER_EPOLL_CLOEXEC([
AC_MSG_NOTICE([Using 'epoll' polling system with CLOEXEC]) AC_MSG_NOTICE([Using 'epoll' I/O thread polling system with CLOEXEC])
AC_DEFINE(ZMQ_USE_EPOLL, 1, [Use 'epoll' polling system]) AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_EPOLL, 1, [Use 'epoll' I/O thread polling system])
AC_DEFINE(ZMQ_USE_EPOLL_CLOEXEC, 1, [Use 'epoll' polling system with CLOEXEC]) AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_EPOLL_CLOEXEC, 1, [Use 'epoll' I/O thread polling system with CLOEXEC])
poller_found=1 poller_found=1
],[ ],[
LIBZMQ_CHECK_POLLER_EPOLL([ LIBZMQ_CHECK_POLLER_EPOLL([
AC_MSG_NOTICE([Using 'epoll' polling system with CLOEXEC]) AC_MSG_NOTICE([Using 'epoll' I/O thread polling system with CLOEXEC])
AC_DEFINE(ZMQ_USE_EPOLL, 1, [Use 'epoll' polling system]) AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_EPOLL, 1, [Use 'epoll' I/O thread polling system])
poller_found=1 poller_found=1
]) ])
]) ])
@ -1103,29 +1108,29 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
;; ;;
devpoll) devpoll)
LIBZMQ_CHECK_POLLER_DEVPOLL([ LIBZMQ_CHECK_POLLER_DEVPOLL([
AC_MSG_NOTICE([Using 'devpoll' polling system]) AC_MSG_NOTICE([Using 'devpoll' I/O thread polling system])
AC_DEFINE(ZMQ_USE_DEVPOLL, 1, [Use 'devpoll' polling system]) AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_DEVPOLL, 1, [Use 'devpoll' I/O thread polling system])
poller_found=1 poller_found=1
]) ])
;; ;;
pollset) pollset)
LIBZMQ_CHECK_POLLER_POLLSET([ LIBZMQ_CHECK_POLLER_POLLSET([
AC_MSG_NOTICE([Using 'pollset' polling system]) AC_MSG_NOTICE([Using 'pollset' I/O thread polling system])
AC_DEFINE(ZMQ_USE_POLLSET, 1, [Use 'pollset' polling system]) AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_POLLSET, 1, [Use 'pollset' I/O thread polling system])
poller_found=1 poller_found=1
]) ])
;; ;;
poll) poll)
LIBZMQ_CHECK_POLLER_POLL([ LIBZMQ_CHECK_POLLER_POLL([
AC_MSG_NOTICE([Using 'poll' polling system]) AC_MSG_NOTICE([Using 'poll' I/O thread polling system])
AC_DEFINE(ZMQ_USE_POLL, 1, [Use 'poll' polling system]) AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_POLL, 1, [Use 'poll' I/O thread polling system])
poller_found=1 poller_found=1
]) ])
;; ;;
select) select)
LIBZMQ_CHECK_POLLER_SELECT([ LIBZMQ_CHECK_POLLER_SELECT([
AC_MSG_NOTICE([Using 'select' polling system]) AC_MSG_NOTICE([Using 'select' I/O thread polling system])
AC_DEFINE(ZMQ_USE_SELECT, 1, [Use 'select' polling system]) AC_DEFINE(ZMQ_IOTHREAD_POLLER_USE_SELECT, 1, [Use 'select' I/O thread polling system])
poller_found=1 poller_found=1
]) ])
;; ;;
@ -1135,4 +1140,25 @@ AC_DEFUN([LIBZMQ_CHECK_POLLER], [{
if test $poller_found -eq 0; then if test $poller_found -eq 0; then
AC_MSG_ERROR([None of '$pollers' are valid pollers on this platform]) AC_MSG_ERROR([None of '$pollers' are valid pollers on this platform])
fi 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__ #ifndef __ZMQ_PLATFORM_HPP_INCLUDED__
#define __ZMQ_PLATFORM_HPP_INCLUDED__ #define __ZMQ_PLATFORM_HPP_INCLUDED__
#cmakedefine ZMQ_USE_KQUEUE #cmakedefine ZMQ_IOTHREAD_POLLER_USE_KQUEUE
#cmakedefine ZMQ_USE_EPOLL #cmakedefine ZMQ_IOTHREAD_POLLER_USE_EPOLL
#cmakedefine ZMQ_USE_EPOLL_CLOEXEC #cmakedefine ZMQ_IOTHREAD_POLLER_USE_EPOLL_CLOEXEC
#cmakedefine ZMQ_USE_DEVPOLL #cmakedefine ZMQ_IOTHREAD_POLLER_USE_DEVPOLL
#cmakedefine ZMQ_USE_POLL #cmakedefine ZMQ_IOTHREAD_POLLER_USE_POLL
#cmakedefine ZMQ_USE_SELECT #cmakedefine ZMQ_IOTHREAD_POLLER_USE_SELECT
#cmakedefine ZMQ_POLL_BASED_ON_SELECT
#cmakedefine ZMQ_POLL_BASED_ON_POLL
#cmakedefine ZMQ_FORCE_MUTEXES #cmakedefine ZMQ_FORCE_MUTEXES

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -32,11 +32,15 @@
// poller.hpp decides which polling mechanism to use. // poller.hpp decides which polling mechanism to use.
#include "poller.hpp" #include "poller.hpp"
#if defined ZMQ_USE_POLL #if defined ZMQ_IOTHREAD_POLLER_USE_POLL
#if !defined ZMQ_HAVE_WINDOWS #if defined ZMQ_HAVE_WINDOWS
#include <poll.h> #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 #endif
#include <poll.h>
#include <stddef.h> #include <stddef.h>
#include <vector> #include <vector>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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