diff --git a/zmq.hpp b/zmq.hpp index 9a84bb3..a9e4447 100644 --- a/zmq.hpp +++ b/zmq.hpp @@ -52,6 +52,7 @@ #ifdef ZMQ_CPP11 #include #include +#include #endif // Detect whether the compiler supports C++11 rvalue references. @@ -490,6 +491,7 @@ namespace zmq class socket_t { friend class monitor_t; + friend class poller_t; public: inline socket_t(context_t& context_, int type_) { @@ -827,6 +829,62 @@ namespace zmq private: void* socketPtr; }; + +#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) + class poller_t + { + public: + poller_t () : poller_ptr (zmq_poller_new ()) + { + if (!poller_ptr) + throw error_t (); + } + + ~poller_t () + { + zmq_poller_destroy (&poller_ptr); + } + + bool add (zmq::socket_t &socket, short events, std::function &handler) + { + if (0 == zmq_poller_add (poller_ptr, socket.ptr, &handler, events)) { + poller_events.emplace_back (zmq_poller_event_t ()); + return true; + } + return false; + } + + bool remove (zmq::socket_t &socket) + { + if (0 == zmq_poller_remove (poller_ptr, socket.ptr)) { + poller_events.pop_back (); + return true; + } + return false; + } + + bool wait (std::chrono::milliseconds timeout) + { + int rc = zmq_poller_wait_all (poller_ptr, poller_events.data (), poller_events.size (), static_cast(timeout.count ())); + if (rc >= 0) { + std::for_each (poller_events.begin (), poller_events.begin () + rc, [](zmq_poller_event_t& event) { + (*reinterpret_cast*> (event.user_data)) (); + }); + return true; + } + + if (zmq_errno () == ETIMEDOUT) + return false; + + throw error_t (); + } + + private: + void *poller_ptr; + std::vector poller_events; + }; +#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) + } #endif