/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file is part of zmqpp. * Copyright (c) 2011-2015 Contributors as noted in the AUTHORS file. */ #pragma once #include #include #include #include #include "compatibility.hpp" #include "poller.hpp" namespace zmqpp { class socket; typedef socket socket_t; /** * Reactor object that helps to manage multiple socket by calling a user-defined handler for each socket * when a watched event occurs. * * It uses zmq::poller as the underlying polling mechanism. */ class reactor { public: typedef std::function Callable; typedef std::pair PollItemCallablePair; /** * Construct an empty polling model. */ reactor(); /** * Cleanup reactor. * * Any sockets will need to be closed separately. */ ~reactor(); /** * Add a socket to the reactor, providing a handler that will be called when the monitored events occur. * * \param socket the socket to monitor. * \param callable the function that will be called by the reactor when a registered event occurs on socket. * \param event the event flags to monitor on the socket. */ void add(socket_t& socket, Callable callable, short const event = poller::poll_in); /*! * Add a standard socket to the reactor, providing a handler that will be called when the monitored events occur. * * \param descriptor the standard socket to monitor (SOCKET under Windows, a file descriptor otherwise). * \param callable the function that will be called by the reactor when a registered event occurs on fd. * \param event the event flags to monitor. */ void add(raw_socket_t const descriptor, Callable callable, short const event = poller::poll_in | poller::poll_error); /** * Check if we are monitoring a given socket with this reactor. * * \param socket the socket to check. * \return true if it is there. */ bool has(socket_t const& socket); /** * Check if we are monitoring a given standard socket with this reactor. * * \param descriptor the raw socket to check (SOCKET under Windows, a file descriptor otherwise). * \return true if it is there. */ bool has(raw_socket_t const descriptor); /** * Stop monitoring a socket. * * \param socket the socket to stop monitoring. */ void remove(socket_t const& socket); /** * Stop monitoring a standard socket. * * \param descriptor the standard socket to stop monitoring. */ void remove(raw_socket_t const descriptor); /** * Update the monitored event flags for a given socket. * * \param socket the socket to update event flags. * \param event the event flags to monitor on the socket. */ void check_for(socket_t const& socket, short const event); /*! * Update the monitored event flags for a given standard socket. * * \param descriptor the raw socket to update event flags (SOCKET under Windows, a file descriptor otherwise). * \param event the event flags to monitor on the socket. */ void check_for(raw_socket_t const descriptor, short const event); /** * Poll for monitored events and call associated handler when needed. * * By default this method will block forever or until at least one of the monitored * sockets or file descriptors has events. * * If a timeout is set and was reached then this function returns false. * * \param timeout milliseconds to timeout. * \return true if there is an event.. */ bool poll(long timeout = poller::wait_forever); /** * Get the event flags triggered for a socket. * * \param socket the socket to get triggered event flags for. * \return the event flags. */ short events(socket_t const& socket) const; /** * Get the event flags triggered for a standard socket. * * \param descriptor the raw socket to get triggered event flags for (SOCKET under Windows, a file descriptor otherwise). * \return the event flags. */ short events(raw_socket_t const descriptor) const; /** * Get a reference to the underlying poller object used by the reactor. * Not sure this is useful. */ poller &get_poller(); /** * Get a reference to the underlying poller object used by the reactor (const version). * Not sure this is useful either. */ const poller &get_poller() const; protected: void add(const zmq_pollitem_t &item, Callable callable); private: std::vector items_; std::vector sockRemoveLater_; std::vector fdRemoveLater_; /** * Flush the fdRemoveLater_ and sockRemoveLater_ vector, effectively removing * the item for the reactor and poller. */ void flush_remove_later(); poller poller_; bool dispatching_; }; }