mirror of
https://github.com/zeromq/cppzmq.git
synced 2024-12-12 10:33:52 +01:00
Problem: Type-safety of poller_t and active_poller_t can be improved (#318)
Problem: Type-safety of poller_t and active_poller_t can be improved
This commit is contained in:
parent
6f0fb2a3ea
commit
0458f7d16c
@ -47,7 +47,7 @@ TEST_CASE("move construct non empty", "[active_poller]")
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
|
||||
zmq::active_poller_t a;
|
||||
a.add(socket, ZMQ_POLLIN, [](short) {});
|
||||
a.add(socket, zmq::event_flags::pollin, [](zmq::event_flags) {});
|
||||
CHECK_FALSE(a.empty());
|
||||
CHECK(1u == a.size());
|
||||
zmq::active_poller_t b = std::move(a);
|
||||
@ -63,7 +63,7 @@ TEST_CASE("move assign non empty", "[active_poller]")
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
|
||||
zmq::active_poller_t a;
|
||||
a.add(socket, ZMQ_POLLIN, [](short) {});
|
||||
a.add(socket, zmq::event_flags::pollin, [](zmq::event_flags) {});
|
||||
CHECK_FALSE(a.empty());
|
||||
CHECK(1u == a.size());
|
||||
zmq::active_poller_t b;
|
||||
@ -79,8 +79,8 @@ TEST_CASE("add handler", "[active_poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::active_poller_t active_poller;
|
||||
zmq::active_poller_t::handler_t handler;
|
||||
CHECK_NOTHROW(active_poller.add(socket, ZMQ_POLLIN, handler));
|
||||
zmq::active_poller_t::handler_type handler;
|
||||
CHECK_NOTHROW(active_poller.add(socket, zmq::event_flags::pollin, handler));
|
||||
}
|
||||
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 0)
|
||||
@ -90,9 +90,9 @@ TEST_CASE("add handler invalid events type", "[active_poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::active_poller_t active_poller;
|
||||
zmq::active_poller_t::handler_t handler;
|
||||
zmq::active_poller_t::handler_type handler;
|
||||
short invalid_events_type = 2 << 10;
|
||||
CHECK_THROWS_AS(active_poller.add(socket, invalid_events_type, handler), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(active_poller.add(socket, static_cast<zmq::event_flags>(invalid_events_type), handler), const zmq::error_t&);
|
||||
CHECK(active_poller.empty());
|
||||
CHECK(0u == active_poller.size());
|
||||
}
|
||||
@ -103,10 +103,10 @@ TEST_CASE("add handler twice throws", "[active_poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::active_poller_t active_poller;
|
||||
zmq::active_poller_t::handler_t handler;
|
||||
active_poller.add(socket, ZMQ_POLLIN, handler);
|
||||
zmq::active_poller_t::handler_type handler;
|
||||
active_poller.add(socket, zmq::event_flags::pollin, handler);
|
||||
/// \todo the actual error code should be checked
|
||||
CHECK_THROWS_AS(active_poller.add(socket, ZMQ_POLLIN, handler), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(active_poller.add(socket, zmq::event_flags::pollin, handler), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("wait with no handlers throws", "[active_poller]")
|
||||
@ -130,7 +130,7 @@ TEST_CASE("remove registered empty", "[active_poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::active_poller_t active_poller;
|
||||
active_poller.add(socket, ZMQ_POLLIN, zmq::active_poller_t::handler_t{});
|
||||
active_poller.add(socket, zmq::event_flags::pollin, zmq::active_poller_t::handler_type{});
|
||||
CHECK_NOTHROW(active_poller.remove(socket));
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ TEST_CASE("remove registered non empty", "[active_poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::active_poller_t active_poller;
|
||||
active_poller.add(socket, ZMQ_POLLIN, [](short) {});
|
||||
active_poller.add(socket, zmq::event_flags::pollin, [](zmq::event_flags) {});
|
||||
CHECK_NOTHROW(active_poller.remove(socket));
|
||||
}
|
||||
|
||||
@ -147,9 +147,9 @@ namespace
|
||||
{
|
||||
struct server_client_setup : common_server_client_setup
|
||||
{
|
||||
zmq::active_poller_t::handler_t handler = [&](short e) { events = e; };
|
||||
zmq::active_poller_t::handler_type handler = [&](zmq::event_flags e) { events = e; };
|
||||
|
||||
short events = 0;
|
||||
zmq::event_flags events = zmq::event_flags::none;
|
||||
};
|
||||
}
|
||||
|
||||
@ -161,11 +161,11 @@ TEST_CASE("poll basic", "[active_poller]")
|
||||
|
||||
zmq::active_poller_t active_poller;
|
||||
bool message_received = false;
|
||||
zmq::active_poller_t::handler_t handler = [&message_received](short events) {
|
||||
CHECK(0 != (events & ZMQ_POLLIN));
|
||||
zmq::active_poller_t::handler_type handler = [&message_received](zmq::event_flags events) {
|
||||
CHECK(zmq::event_flags::none != (events & zmq::event_flags::pollin));
|
||||
message_received = true;
|
||||
};
|
||||
CHECK_NOTHROW(active_poller.add(s.server, ZMQ_POLLIN, handler));
|
||||
CHECK_NOTHROW(active_poller.add(s.server, zmq::event_flags::pollin, handler));
|
||||
CHECK(1 == active_poller.wait(std::chrono::milliseconds{-1}));
|
||||
CHECK(message_received);
|
||||
}
|
||||
@ -180,33 +180,33 @@ TEST_CASE("client server", "[active_poller]")
|
||||
|
||||
// Setup active_poller
|
||||
zmq::active_poller_t active_poller;
|
||||
short events;
|
||||
zmq::active_poller_t::handler_t handler = [&](short e) {
|
||||
if (0 != (e & ZMQ_POLLIN)) {
|
||||
zmq::event_flags events;
|
||||
zmq::active_poller_t::handler_type handler = [&](zmq::event_flags e) {
|
||||
if (zmq::event_flags::none != (e & zmq::event_flags::pollin)) {
|
||||
zmq::message_t zmq_msg;
|
||||
CHECK_NOTHROW(s.server.recv(zmq_msg)); // get message
|
||||
std::string recv_msg(zmq_msg.data<char>(), zmq_msg.size());
|
||||
CHECK(send_msg == recv_msg);
|
||||
} else if (0 != (e & ~ZMQ_POLLOUT)) {
|
||||
INFO("Unexpected event type " << events);
|
||||
} else if (zmq::event_flags::none != (e & ~zmq::event_flags::pollout)) {
|
||||
INFO("Unexpected event type " << static_cast<short>(events));
|
||||
REQUIRE(false);
|
||||
}
|
||||
events = e;
|
||||
};
|
||||
|
||||
CHECK_NOTHROW(active_poller.add(s.server, ZMQ_POLLIN, handler));
|
||||
CHECK_NOTHROW(active_poller.add(s.server, zmq::event_flags::pollin, handler));
|
||||
|
||||
// client sends message
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{send_msg}, zmq::send_flags::none));
|
||||
|
||||
CHECK(1 == active_poller.wait(std::chrono::milliseconds{-1}));
|
||||
CHECK(events == ZMQ_POLLIN);
|
||||
CHECK(events == zmq::event_flags::pollin);
|
||||
|
||||
// Re-add server socket with pollout flag
|
||||
CHECK_NOTHROW(active_poller.remove(s.server));
|
||||
CHECK_NOTHROW(active_poller.add(s.server, ZMQ_POLLIN | ZMQ_POLLOUT, handler));
|
||||
CHECK_NOTHROW(active_poller.add(s.server, zmq::event_flags::pollin | zmq::event_flags::pollout, handler));
|
||||
CHECK(1 == active_poller.wait(std::chrono::milliseconds{-1}));
|
||||
CHECK(events == ZMQ_POLLOUT);
|
||||
CHECK(events == zmq::event_flags::pollout);
|
||||
}
|
||||
|
||||
TEST_CASE("add invalid socket throws", "[active_poller]")
|
||||
@ -215,7 +215,7 @@ TEST_CASE("add invalid socket throws", "[active_poller]")
|
||||
zmq::active_poller_t active_poller;
|
||||
zmq::socket_t a{context, zmq::socket_type::router};
|
||||
zmq::socket_t b{std::move(a)};
|
||||
CHECK_THROWS_AS(active_poller.add(a, ZMQ_POLLIN, zmq::active_poller_t::handler_t{}),
|
||||
CHECK_THROWS_AS(active_poller.add(a, zmq::event_flags::pollin, zmq::active_poller_t::handler_type{}),
|
||||
const zmq::error_t&);
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ TEST_CASE("remove invalid socket throws", "[active_poller]")
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::active_poller_t active_poller;
|
||||
CHECK_NOTHROW(
|
||||
active_poller.add(socket, ZMQ_POLLIN, zmq::active_poller_t::handler_t{}));
|
||||
active_poller.add(socket, zmq::event_flags::pollin, zmq::active_poller_t::handler_type{}));
|
||||
CHECK(1u == active_poller.size());
|
||||
std::vector<zmq::socket_t> sockets;
|
||||
sockets.emplace_back(std::move(socket));
|
||||
@ -238,8 +238,8 @@ TEST_CASE("wait on added empty handler", "[active_poller]")
|
||||
server_client_setup s;
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
zmq::active_poller_t active_poller;
|
||||
zmq::active_poller_t::handler_t handler;
|
||||
CHECK_NOTHROW(active_poller.add(s.server, ZMQ_POLLIN, handler));
|
||||
zmq::active_poller_t::handler_type handler;
|
||||
CHECK_NOTHROW(active_poller.add(s.server, zmq::event_flags::pollin, handler));
|
||||
CHECK_NOTHROW(active_poller.wait(std::chrono::milliseconds{-1}));
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ TEST_CASE("modify empty throws", "[active_poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::push};
|
||||
zmq::active_poller_t active_poller;
|
||||
CHECK_THROWS_AS(active_poller.modify(socket, ZMQ_POLLIN), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(active_poller.modify(socket, zmq::event_flags::pollin), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("modify invalid socket throws", "[active_poller]")
|
||||
@ -257,7 +257,7 @@ TEST_CASE("modify invalid socket throws", "[active_poller]")
|
||||
zmq::socket_t a{context, zmq::socket_type::push};
|
||||
zmq::socket_t b{std::move(a)};
|
||||
zmq::active_poller_t active_poller;
|
||||
CHECK_THROWS_AS(active_poller.modify(a, ZMQ_POLLIN), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(active_poller.modify(a, zmq::event_flags::pollin), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("modify not added throws", "[active_poller]")
|
||||
@ -267,8 +267,8 @@ TEST_CASE("modify not added throws", "[active_poller]")
|
||||
zmq::socket_t b{context, zmq::socket_type::push};
|
||||
zmq::active_poller_t active_poller;
|
||||
CHECK_NOTHROW(
|
||||
active_poller.add(a, ZMQ_POLLIN, zmq::active_poller_t::handler_t{}));
|
||||
CHECK_THROWS_AS(active_poller.modify(b, ZMQ_POLLIN), const zmq::error_t&);
|
||||
active_poller.add(a, zmq::event_flags::pollin, zmq::active_poller_t::handler_type{}));
|
||||
CHECK_THROWS_AS(active_poller.modify(b, zmq::event_flags::pollin), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("modify simple", "[active_poller]")
|
||||
@ -277,8 +277,8 @@ TEST_CASE("modify simple", "[active_poller]")
|
||||
zmq::socket_t a{context, zmq::socket_type::push};
|
||||
zmq::active_poller_t active_poller;
|
||||
CHECK_NOTHROW(
|
||||
active_poller.add(a, ZMQ_POLLIN, zmq::active_poller_t::handler_t{}));
|
||||
CHECK_NOTHROW(active_poller.modify(a, ZMQ_POLLIN | ZMQ_POLLOUT));
|
||||
active_poller.add(a, zmq::event_flags::pollin, zmq::active_poller_t::handler_type{}));
|
||||
CHECK_NOTHROW(active_poller.modify(a, zmq::event_flags::pollin | zmq::event_flags::pollout));
|
||||
}
|
||||
|
||||
TEST_CASE("poll client server", "[active_poller]")
|
||||
@ -288,19 +288,19 @@ TEST_CASE("poll client server", "[active_poller]")
|
||||
|
||||
// Setup active_poller
|
||||
zmq::active_poller_t active_poller;
|
||||
CHECK_NOTHROW(active_poller.add(s.server, ZMQ_POLLIN, s.handler));
|
||||
CHECK_NOTHROW(active_poller.add(s.server, zmq::event_flags::pollin, s.handler));
|
||||
|
||||
// client sends message
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
|
||||
// wait for message and verify events
|
||||
CHECK_NOTHROW(active_poller.wait(std::chrono::milliseconds{500}));
|
||||
CHECK(s.events == ZMQ_POLLIN);
|
||||
CHECK(s.events == zmq::event_flags::pollin);
|
||||
|
||||
// Modify server socket with pollout flag
|
||||
CHECK_NOTHROW(active_poller.modify(s.server, ZMQ_POLLIN | ZMQ_POLLOUT));
|
||||
CHECK_NOTHROW(active_poller.modify(s.server, zmq::event_flags::pollin | zmq::event_flags::pollout));
|
||||
CHECK(1 == active_poller.wait(std::chrono::milliseconds{500}));
|
||||
CHECK(s.events == (ZMQ_POLLIN | ZMQ_POLLOUT));
|
||||
CHECK(s.events == (zmq::event_flags::pollin | zmq::event_flags::pollout));
|
||||
}
|
||||
|
||||
TEST_CASE("wait one return", "[active_poller]")
|
||||
@ -313,7 +313,7 @@ TEST_CASE("wait one return", "[active_poller]")
|
||||
// Setup active_poller
|
||||
zmq::active_poller_t active_poller;
|
||||
CHECK_NOTHROW(
|
||||
active_poller.add(s.server, ZMQ_POLLIN, [&count](short) { ++count; }));
|
||||
active_poller.add(s.server, zmq::event_flags::pollin, [&count](zmq::event_flags) { ++count; }));
|
||||
|
||||
// client sends message
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
@ -328,8 +328,8 @@ TEST_CASE("wait on move constructed active_poller", "[active_poller]")
|
||||
server_client_setup s;
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
zmq::active_poller_t a;
|
||||
zmq::active_poller_t::handler_t handler;
|
||||
CHECK_NOTHROW(a.add(s.server, ZMQ_POLLIN, handler));
|
||||
zmq::active_poller_t::handler_type handler;
|
||||
CHECK_NOTHROW(a.add(s.server, zmq::event_flags::pollin, handler));
|
||||
zmq::active_poller_t b{std::move(a)};
|
||||
CHECK(1u == b.size());
|
||||
/// \todo the actual error code should be checked
|
||||
@ -342,8 +342,8 @@ TEST_CASE("wait on move assigned active_poller", "[active_poller]")
|
||||
server_client_setup s;
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
zmq::active_poller_t a;
|
||||
zmq::active_poller_t::handler_t handler;
|
||||
CHECK_NOTHROW(a.add(s.server, ZMQ_POLLIN, handler));
|
||||
zmq::active_poller_t::handler_type handler;
|
||||
CHECK_NOTHROW(a.add(s.server, zmq::event_flags::pollin, handler));
|
||||
zmq::active_poller_t b;
|
||||
b = {std::move(a)};
|
||||
CHECK(1u == b.size());
|
||||
@ -359,7 +359,7 @@ TEST_CASE("received on move constructed active_poller", "[active_poller]")
|
||||
int count = 0;
|
||||
// Setup active_poller a
|
||||
zmq::active_poller_t a;
|
||||
CHECK_NOTHROW(a.add(s.server, ZMQ_POLLIN, [&count](short) { ++count; }));
|
||||
CHECK_NOTHROW(a.add(s.server, zmq::event_flags::pollin, [&count](zmq::event_flags) { ++count; }));
|
||||
// client sends message
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
// wait for message and verify it is received
|
||||
@ -389,8 +389,8 @@ TEST_CASE("remove from handler", "[active_poller]")
|
||||
int count = 0;
|
||||
for (size_t i = 0; i < ITER_NO; ++i) {
|
||||
CHECK_NOTHROW(
|
||||
active_poller.add(setup_list[i].server, ZMQ_POLLIN, [&, i](short events) {
|
||||
CHECK(events == ZMQ_POLLIN);
|
||||
active_poller.add(setup_list[i].server, zmq::event_flags::pollin, [&, i](zmq::event_flags events) {
|
||||
CHECK(events == zmq::event_flags::pollin);
|
||||
active_poller.remove(setup_list[ITER_NO - i - 1].server);
|
||||
CHECK((ITER_NO - i - 1) == active_poller.size());
|
||||
}));
|
||||
|
100
tests/poller.cpp
100
tests/poller.cpp
@ -1,25 +1,33 @@
|
||||
#include "testutil.hpp"
|
||||
|
||||
#if defined(ZMQ_CPP11) && defined(ZMQ_BUILD_DRAFT_API)
|
||||
#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#if (__cplusplus >= 201703L)
|
||||
static_assert(std::is_nothrow_swappable<zmq::poller_t<>>::value,
|
||||
"poller_t should be nothrow swappable");
|
||||
#ifdef ZMQ_CPP17
|
||||
static_assert(std::is_nothrow_swappable_v<zmq::poller_t<>>);
|
||||
#endif
|
||||
|
||||
TEST_CASE("poller create destroy", "[poller]")
|
||||
{
|
||||
zmq::poller_t<> poller;
|
||||
}
|
||||
static_assert(sizeof(zmq_poller_event_t) == sizeof(zmq::poller_event<>), "");
|
||||
static_assert(sizeof(zmq_poller_event_t) == sizeof(zmq::poller_event<zmq::no_user_data>), "");
|
||||
static_assert(sizeof(zmq_poller_event_t) == sizeof(zmq::poller_event<int>), "");
|
||||
static_assert(alignof(zmq_poller_event_t) == alignof(zmq::poller_event<>), "");
|
||||
static_assert(alignof(zmq_poller_event_t) == alignof(zmq::poller_event<int>), "");
|
||||
|
||||
static_assert(!std::is_copy_constructible<zmq::poller_t<>>::value,
|
||||
"poller_t should not be copy-constructible");
|
||||
static_assert(!std::is_copy_assignable<zmq::poller_t<>>::value,
|
||||
"poller_t should not be copy-assignable");
|
||||
|
||||
TEST_CASE("poller create destroy", "[poller]")
|
||||
{
|
||||
zmq::poller_t<> a;
|
||||
#ifdef ZMQ_CPP17 // CTAD
|
||||
zmq::poller_t b;
|
||||
zmq::poller_event e;
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("poller move construct empty", "[poller]")
|
||||
{
|
||||
zmq::poller_t<> a;
|
||||
@ -47,7 +55,7 @@ TEST_CASE("poller move construct non empty", "[poller]")
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
|
||||
zmq::poller_t<> a;
|
||||
a.add(socket, ZMQ_POLLIN, nullptr);
|
||||
a.add(socket, zmq::event_flags::pollin);
|
||||
zmq::poller_t<> b = std::move(a);
|
||||
}
|
||||
|
||||
@ -57,7 +65,7 @@ TEST_CASE("poller move assign non empty", "[poller]")
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
|
||||
zmq::poller_t<> a;
|
||||
a.add(socket, ZMQ_POLLIN, nullptr);
|
||||
a.add(socket, zmq::event_flags::pollin);
|
||||
zmq::poller_t<> b;
|
||||
b = std::move(a);
|
||||
}
|
||||
@ -66,17 +74,17 @@ TEST_CASE("poller add nullptr", "[poller]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::poller_t<> poller;
|
||||
CHECK_NOTHROW(poller.add(socket, ZMQ_POLLIN, nullptr));
|
||||
zmq::poller_t<void> poller;
|
||||
CHECK_NOTHROW(poller.add(socket, zmq::event_flags::pollin, nullptr));
|
||||
}
|
||||
|
||||
TEST_CASE("poller add non nullptr", "[poller]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::poller_t<> poller;
|
||||
zmq::poller_t<int> poller;
|
||||
int i;
|
||||
CHECK_NOTHROW(poller.add(socket, ZMQ_POLLIN, &i));
|
||||
CHECK_NOTHROW(poller.add(socket, zmq::event_flags::pollin, &i));
|
||||
}
|
||||
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 0)
|
||||
@ -87,7 +95,7 @@ TEST_CASE("poller add handler invalid events type", "[poller]")
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::poller_t<> poller;
|
||||
short invalid_events_type = 2 << 10;
|
||||
CHECK_THROWS_AS(poller.add(socket, invalid_events_type, nullptr), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(poller.add(socket, static_cast<zmq::event_flags>(invalid_events_type)), const zmq::error_t&);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -96,15 +104,15 @@ TEST_CASE("poller add handler twice throws", "[poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::poller_t<> poller;
|
||||
poller.add(socket, ZMQ_POLLIN, nullptr);
|
||||
poller.add(socket, zmq::event_flags::pollin);
|
||||
/// \todo the actual error code should be checked
|
||||
CHECK_THROWS_AS(poller.add(socket, ZMQ_POLLIN, nullptr), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(poller.add(socket, zmq::event_flags::pollin), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("poller wait with no handlers throws", "[poller]")
|
||||
{
|
||||
zmq::poller_t<> poller;
|
||||
std::vector<zmq_poller_event_t> events;
|
||||
std::vector<zmq::poller_event<>> events;
|
||||
/// \todo the actual error code should be checked
|
||||
CHECK_THROWS_AS(poller.wait_all(events, std::chrono::milliseconds{10}),
|
||||
const zmq::error_t&);
|
||||
@ -124,7 +132,7 @@ TEST_CASE("poller remove registered empty", "[poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::poller_t<> poller;
|
||||
poller.add(socket, ZMQ_POLLIN, nullptr);
|
||||
poller.add(socket, zmq::event_flags::pollin);
|
||||
CHECK_NOTHROW(poller.remove(socket));
|
||||
}
|
||||
|
||||
@ -132,9 +140,9 @@ TEST_CASE("poller remove registered non empty", "[poller]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::poller_t<> poller;
|
||||
zmq::poller_t<int> poller;
|
||||
int empty{};
|
||||
poller.add(socket, ZMQ_POLLIN, &empty);
|
||||
poller.add(socket, zmq::event_flags::pollin, &empty);
|
||||
CHECK_NOTHROW(poller.remove(socket));
|
||||
}
|
||||
|
||||
@ -145,9 +153,9 @@ TEST_CASE("poller poll basic", "[poller]")
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
|
||||
zmq::poller_t<int> poller;
|
||||
std::vector<zmq_poller_event_t> events{1};
|
||||
std::vector<zmq::poller_event<int>> events{1};
|
||||
int i = 0;
|
||||
CHECK_NOTHROW(poller.add(s.server, ZMQ_POLLIN, &i));
|
||||
CHECK_NOTHROW(poller.add(s.server, zmq::event_flags::pollin, &i));
|
||||
CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{-1}));
|
||||
CHECK(s.server == events[0].socket);
|
||||
CHECK(&i == events[0].user_data);
|
||||
@ -159,7 +167,7 @@ TEST_CASE("poller add invalid socket throws", "[poller]")
|
||||
zmq::poller_t<> poller;
|
||||
zmq::socket_t a{context, zmq::socket_type::router};
|
||||
zmq::socket_t b{std::move(a)};
|
||||
CHECK_THROWS_AS(poller.add(a, ZMQ_POLLIN, nullptr), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(poller.add(a, zmq::event_flags::pollin), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("poller remove invalid socket throws", "[poller]")
|
||||
@ -167,7 +175,7 @@ TEST_CASE("poller remove invalid socket throws", "[poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::router};
|
||||
zmq::poller_t<> poller;
|
||||
CHECK_NOTHROW(poller.add(socket, ZMQ_POLLIN, nullptr));
|
||||
CHECK_NOTHROW(poller.add(socket, zmq::event_flags::pollin));
|
||||
std::vector<zmq::socket_t> sockets;
|
||||
sockets.emplace_back(std::move(socket));
|
||||
CHECK_THROWS_AS(poller.remove(socket), const zmq::error_t&);
|
||||
@ -179,7 +187,7 @@ TEST_CASE("poller modify empty throws", "[poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket{context, zmq::socket_type::push};
|
||||
zmq::poller_t<> poller;
|
||||
CHECK_THROWS_AS(poller.modify(socket, ZMQ_POLLIN), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(poller.modify(socket, zmq::event_flags::pollin), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("poller modify invalid socket throws", "[poller]")
|
||||
@ -188,7 +196,7 @@ TEST_CASE("poller modify invalid socket throws", "[poller]")
|
||||
zmq::socket_t a{context, zmq::socket_type::push};
|
||||
zmq::socket_t b{std::move(a)};
|
||||
zmq::poller_t<> poller;
|
||||
CHECK_THROWS_AS(poller.modify(a, ZMQ_POLLIN), const zmq::error_t&);
|
||||
CHECK_THROWS_AS(poller.modify(a, zmq::event_flags::pollin), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("poller modify not added throws", "[poller]")
|
||||
@ -197,8 +205,8 @@ TEST_CASE("poller modify not added throws", "[poller]")
|
||||
zmq::socket_t a{context, zmq::socket_type::push};
|
||||
zmq::socket_t b{context, zmq::socket_type::push};
|
||||
zmq::poller_t<> poller;
|
||||
CHECK_NOTHROW(poller.add(a, ZMQ_POLLIN, nullptr));
|
||||
CHECK_THROWS_AS(poller.modify(b, ZMQ_POLLIN), const zmq::error_t&);
|
||||
CHECK_NOTHROW(poller.add(a, zmq::event_flags::pollin));
|
||||
CHECK_THROWS_AS(poller.modify(b, zmq::event_flags::pollin), const zmq::error_t&);
|
||||
}
|
||||
|
||||
TEST_CASE("poller modify simple", "[poller]")
|
||||
@ -206,8 +214,8 @@ TEST_CASE("poller modify simple", "[poller]")
|
||||
zmq::context_t context;
|
||||
zmq::socket_t a{context, zmq::socket_type::push};
|
||||
zmq::poller_t<> poller;
|
||||
CHECK_NOTHROW(poller.add(a, ZMQ_POLLIN, nullptr));
|
||||
CHECK_NOTHROW(poller.modify(a, ZMQ_POLLIN | ZMQ_POLLOUT));
|
||||
CHECK_NOTHROW(poller.add(a, zmq::event_flags::pollin));
|
||||
CHECK_NOTHROW(poller.modify(a, zmq::event_flags::pollin | zmq::event_flags::pollout));
|
||||
}
|
||||
|
||||
TEST_CASE("poller poll client server", "[poller]")
|
||||
@ -216,21 +224,21 @@ TEST_CASE("poller poll client server", "[poller]")
|
||||
common_server_client_setup s;
|
||||
|
||||
// Setup poller
|
||||
zmq::poller_t<> poller;
|
||||
CHECK_NOTHROW(poller.add(s.server, ZMQ_POLLIN, s.server));
|
||||
zmq::poller_t<zmq::socket_t> poller;
|
||||
CHECK_NOTHROW(poller.add(s.server, zmq::event_flags::pollin, &s.server));
|
||||
|
||||
// client sends message
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
|
||||
// wait for message and verify events
|
||||
std::vector<zmq_poller_event_t> events(1);
|
||||
std::vector<zmq::poller_event<zmq::socket_t>> events(1);
|
||||
CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
|
||||
CHECK(ZMQ_POLLIN == events[0].events);
|
||||
CHECK(zmq::event_flags::pollin == events[0].events);
|
||||
|
||||
// Modify server socket with pollout flag
|
||||
CHECK_NOTHROW(poller.modify(s.server, ZMQ_POLLIN | ZMQ_POLLOUT));
|
||||
CHECK_NOTHROW(poller.modify(s.server, zmq::event_flags::pollin | zmq::event_flags::pollout));
|
||||
CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
|
||||
CHECK((ZMQ_POLLIN | ZMQ_POLLOUT) == events[0].events);
|
||||
CHECK((zmq::event_flags::pollin | zmq::event_flags::pollout) == events[0].events);
|
||||
}
|
||||
|
||||
TEST_CASE("poller wait one return", "[poller]")
|
||||
@ -240,13 +248,13 @@ TEST_CASE("poller wait one return", "[poller]")
|
||||
|
||||
// Setup poller
|
||||
zmq::poller_t<> poller;
|
||||
CHECK_NOTHROW(poller.add(s.server, ZMQ_POLLIN, nullptr));
|
||||
CHECK_NOTHROW(poller.add(s.server, zmq::event_flags::pollin));
|
||||
|
||||
// client sends message
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
|
||||
// wait for message and verify events
|
||||
std::vector<zmq_poller_event_t> events(1);
|
||||
std::vector<zmq::poller_event<>> events(1);
|
||||
CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
|
||||
}
|
||||
|
||||
@ -255,9 +263,9 @@ TEST_CASE("poller wait on move constructed", "[poller]")
|
||||
common_server_client_setup s;
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
zmq::poller_t<> a;
|
||||
CHECK_NOTHROW(a.add(s.server, ZMQ_POLLIN, nullptr));
|
||||
CHECK_NOTHROW(a.add(s.server, zmq::event_flags::pollin));
|
||||
zmq::poller_t<> b{std::move(a)};
|
||||
std::vector<zmq_poller_event_t> events(1);
|
||||
std::vector<zmq::poller_event<>> events(1);
|
||||
/// \todo the actual error code should be checked
|
||||
CHECK_THROWS_AS(a.wait_all(events, std::chrono::milliseconds{10}), const zmq::error_t&);
|
||||
CHECK(1 == b.wait_all(events, std::chrono::milliseconds{-1}));
|
||||
@ -268,11 +276,11 @@ TEST_CASE("poller wait on move assigned", "[poller]")
|
||||
common_server_client_setup s;
|
||||
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}, zmq::send_flags::none));
|
||||
zmq::poller_t<> a;
|
||||
CHECK_NOTHROW(a.add(s.server, ZMQ_POLLIN, nullptr));
|
||||
CHECK_NOTHROW(a.add(s.server, zmq::event_flags::pollin));
|
||||
zmq::poller_t<> b;
|
||||
b = {std::move(a)};
|
||||
/// \todo the TEST_CASE error code should be checked
|
||||
std::vector<zmq_poller_event_t> events(1);
|
||||
std::vector<zmq::poller_event<>> events(1);
|
||||
CHECK_THROWS_AS(a.wait_all(events, std::chrono::milliseconds{10}), const zmq::error_t&);
|
||||
CHECK(1 == b.wait_all(events, std::chrono::milliseconds{-1}));
|
||||
}
|
||||
@ -289,7 +297,7 @@ TEST_CASE("poller remove from handler", "[poller]")
|
||||
// Setup poller
|
||||
zmq::poller_t<> poller;
|
||||
for (size_t i = 0; i < ITER_NO; ++i) {
|
||||
CHECK_NOTHROW(poller.add(setup_list[i].server, ZMQ_POLLIN, nullptr));
|
||||
CHECK_NOTHROW(poller.add(setup_list[i].server, zmq::event_flags::pollin));
|
||||
}
|
||||
// Clients send messages
|
||||
for (auto &s : setup_list) {
|
||||
@ -303,7 +311,7 @@ TEST_CASE("poller remove from handler", "[poller]")
|
||||
}
|
||||
|
||||
// Fire all handlers in one wait
|
||||
std::vector<zmq_poller_event_t> events(ITER_NO);
|
||||
std::vector<zmq::poller_event<>> events(ITER_NO);
|
||||
CHECK(ITER_NO == poller.wait_all(events, std::chrono::milliseconds{-1}));
|
||||
}
|
||||
|
||||
|
97
zmq.hpp
97
zmq.hpp
@ -1823,18 +1823,65 @@ class monitor_t
|
||||
};
|
||||
|
||||
#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
|
||||
template<typename T = void> class poller_t
|
||||
|
||||
// polling events
|
||||
enum class event_flags : short
|
||||
{
|
||||
none = 0,
|
||||
pollin = ZMQ_POLLIN,
|
||||
pollout = ZMQ_POLLOUT,
|
||||
pollerr = ZMQ_POLLERR,
|
||||
pollpri = ZMQ_POLLPRI
|
||||
};
|
||||
|
||||
constexpr event_flags operator|(event_flags a, event_flags b) noexcept
|
||||
{
|
||||
return static_cast<event_flags>(static_cast<short>(a) | static_cast<short>(b));
|
||||
}
|
||||
constexpr event_flags operator&(event_flags a, event_flags b) noexcept
|
||||
{
|
||||
return static_cast<event_flags>(static_cast<short>(a) & static_cast<short>(b));
|
||||
}
|
||||
constexpr event_flags operator~(event_flags a) noexcept
|
||||
{
|
||||
return static_cast<event_flags>(~static_cast<short>(a));
|
||||
}
|
||||
|
||||
struct no_user_data;
|
||||
|
||||
// layout compatible with zmq_poller_event_t
|
||||
template<class T = no_user_data>
|
||||
struct poller_event
|
||||
{
|
||||
socket_ref socket;
|
||||
#ifdef _WIN32
|
||||
SOCKET fd;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
T *user_data;
|
||||
event_flags events;
|
||||
};
|
||||
|
||||
template<typename T = no_user_data> class poller_t
|
||||
{
|
||||
public:
|
||||
using event_type = poller_event<T>;
|
||||
|
||||
poller_t() = default;
|
||||
|
||||
void add(zmq::socket_ref socket, short events, T *user_data)
|
||||
template<
|
||||
typename Dummy = void,
|
||||
typename =
|
||||
typename std::enable_if<!std::is_same<T, no_user_data>::value, Dummy>::type>
|
||||
void add(zmq::socket_ref socket, event_flags events, T *user_data)
|
||||
{
|
||||
if (0
|
||||
!= zmq_poller_add(poller_ptr.get(), socket.handle(),
|
||||
user_data, events)) {
|
||||
throw error_t();
|
||||
}
|
||||
add_impl(socket, events, user_data);
|
||||
}
|
||||
|
||||
void add(zmq::socket_ref socket, event_flags events)
|
||||
{
|
||||
add_impl(socket, events, nullptr);
|
||||
}
|
||||
|
||||
void remove(zmq::socket_ref socket)
|
||||
@ -1844,21 +1891,23 @@ template<typename T = void> class poller_t
|
||||
}
|
||||
}
|
||||
|
||||
void modify(zmq::socket_ref socket, short events)
|
||||
void modify(zmq::socket_ref socket, event_flags events)
|
||||
{
|
||||
if (0
|
||||
!= zmq_poller_modify(poller_ptr.get(), socket.handle(),
|
||||
events)) {
|
||||
static_cast<short>(events))) {
|
||||
throw error_t();
|
||||
}
|
||||
}
|
||||
|
||||
size_t wait_all(std::vector<zmq_poller_event_t> &poller_events,
|
||||
size_t wait_all(std::vector<event_type> &poller_events,
|
||||
const std::chrono::milliseconds timeout)
|
||||
{
|
||||
int rc = zmq_poller_wait_all(poller_ptr.get(), poller_events.data(),
|
||||
static_cast<int>(poller_events.size()),
|
||||
static_cast<long>(timeout.count()));
|
||||
int rc = zmq_poller_wait_all(
|
||||
poller_ptr.get(),
|
||||
reinterpret_cast<zmq_poller_event_t *>(poller_events.data()),
|
||||
static_cast<int>(poller_events.size()),
|
||||
static_cast<long>(timeout.count()));
|
||||
if (rc > 0)
|
||||
return static_cast<size_t>(rc);
|
||||
|
||||
@ -1873,18 +1922,30 @@ template<typename T = void> class poller_t
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<void, void(*)(void *)> poller_ptr{
|
||||
struct destroy_poller_t
|
||||
{
|
||||
void operator()(void *ptr) noexcept
|
||||
{
|
||||
int rc = zmq_poller_destroy(&ptr);
|
||||
ZMQ_ASSERT(rc == 0);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<void, destroy_poller_t> poller_ptr{
|
||||
[]() {
|
||||
auto poller_new = zmq_poller_new();
|
||||
if (poller_new)
|
||||
return poller_new;
|
||||
throw error_t();
|
||||
}(), &destroy_poller};
|
||||
}()};
|
||||
|
||||
static void destroy_poller(void *ptr)
|
||||
void add_impl(zmq::socket_ref socket, event_flags events, T *user_data)
|
||||
{
|
||||
int rc = zmq_poller_destroy(&ptr);
|
||||
ZMQ_ASSERT(rc == 0);
|
||||
if (0
|
||||
!= zmq_poller_add(poller_ptr.get(), socket.handle(),
|
||||
user_data, static_cast<short>(events))) {
|
||||
throw error_t();
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
|
||||
|
@ -382,15 +382,15 @@ class active_poller_t
|
||||
active_poller_t(active_poller_t &&src) = default;
|
||||
active_poller_t &operator=(active_poller_t &&src) = default;
|
||||
|
||||
using handler_t = std::function<void(short)>;
|
||||
using handler_type = std::function<void(event_flags)>;
|
||||
|
||||
void add(zmq::socket_ref socket, short events, handler_t handler)
|
||||
void add(zmq::socket_ref socket, event_flags events, handler_type handler)
|
||||
{
|
||||
auto it = decltype(handlers)::iterator{};
|
||||
auto inserted = bool{};
|
||||
std::tie(it, inserted) =
|
||||
handlers.emplace(socket,
|
||||
std::make_shared<handler_t>(std::move(handler)));
|
||||
std::make_shared<handler_type>(std::move(handler)));
|
||||
try {
|
||||
base_poller.add(socket, events,
|
||||
inserted && *(it->second) ? it->second.get() : nullptr);
|
||||
@ -412,7 +412,7 @@ class active_poller_t
|
||||
need_rebuild = true;
|
||||
}
|
||||
|
||||
void modify(zmq::socket_ref socket, short events)
|
||||
void modify(zmq::socket_ref socket, event_flags events)
|
||||
{
|
||||
base_poller.modify(socket, events);
|
||||
}
|
||||
@ -429,26 +429,25 @@ class active_poller_t
|
||||
need_rebuild = false;
|
||||
}
|
||||
const auto count = base_poller.wait_all(poller_events, timeout);
|
||||
std::for_each(poller_events.begin(), poller_events.begin() + count,
|
||||
[](zmq_poller_event_t &event) {
|
||||
if (event.user_data != NULL)
|
||||
(*reinterpret_cast<handler_t *>(event.user_data))(
|
||||
event.events);
|
||||
std::for_each(poller_events.begin(), poller_events.begin() + static_cast<ptrdiff_t>(count),
|
||||
[](decltype(base_poller)::event_type &event) {
|
||||
if (event.user_data != nullptr)
|
||||
(*event.user_data)(event.events);
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
bool empty() const { return handlers.empty(); }
|
||||
ZMQ_NODISCARD bool empty() const noexcept { return handlers.empty(); }
|
||||
|
||||
size_t size() const { return handlers.size(); }
|
||||
size_t size() const noexcept { return handlers.size(); }
|
||||
|
||||
private:
|
||||
bool need_rebuild{false};
|
||||
|
||||
poller_t<handler_t> base_poller{};
|
||||
std::unordered_map<socket_ref, std::shared_ptr<handler_t>> handlers{};
|
||||
std::vector<zmq_poller_event_t> poller_events{};
|
||||
std::vector<std::shared_ptr<handler_t>> poller_handlers{};
|
||||
poller_t<handler_type> base_poller{};
|
||||
std::unordered_map<socket_ref, std::shared_ptr<handler_type>> handlers{};
|
||||
std::vector<decltype(base_poller)::event_type> poller_events{};
|
||||
std::vector<std::shared_ptr<handler_type>> poller_handlers{};
|
||||
}; // class active_poller_t
|
||||
#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user