245 lines
6.8 KiB
C++
245 lines
6.8 KiB
C++
/*
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
*
|
|
* \date 9 Aug 2011
|
|
* \author Ben Gray (\@benjamg)
|
|
*/
|
|
|
|
#ifndef ZMQPP_POLLER_HPP_
|
|
#define ZMQPP_POLLER_HPP_
|
|
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "compatibility.hpp"
|
|
|
|
namespace zmqpp
|
|
{
|
|
|
|
class socket;
|
|
typedef socket socket_t;
|
|
|
|
/**
|
|
* Polling wrapper.
|
|
*
|
|
* Allows access to polling for any number of zmq sockets or standard sockets.
|
|
*/
|
|
class ZMQPP_EXPORT poller
|
|
{
|
|
public:
|
|
enum {
|
|
wait_forever = -1 /*!< Block forever flag, default setting. */
|
|
};
|
|
|
|
enum : short {
|
|
poll_none = 0, /*!< No polling flags set. */
|
|
poll_in = ZMQ_POLLIN, /*!< Monitor inbound flag. */
|
|
poll_out = ZMQ_POLLOUT, /*!< Monitor output flag. */
|
|
poll_error = ZMQ_POLLERR, /*!< Monitor error flag.\n Only for file descriptors. */
|
|
#if ((ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR >= 2) || ZMQ_VERSION_MAJOR > 4)
|
|
poll_pri = ZMQ_POLLPRI /*!< Priority input flag.\n Only for file descriptors. See POLLPRI) */
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* Construct an empty polling model.
|
|
*/
|
|
poller();
|
|
|
|
/**
|
|
* Cleanup poller.
|
|
*
|
|
* Any sockets will need to be closed separately.
|
|
*/
|
|
~poller();
|
|
|
|
/**
|
|
* Add a socket to the polling model and set which events to monitor.
|
|
*
|
|
* \param socket the socket to monitor.
|
|
* \param event the event flags to monitor on the socket.
|
|
*/
|
|
void add(socket_t& socket, short const event = poll_in);
|
|
|
|
/**
|
|
* Add a standard socket to the polling model and set which events to monitor.
|
|
*
|
|
* \param descriptor the raw socket to monitor (SOCKET under Windows, a file descriptor otherwise).
|
|
* \param event the event flags to monitor.
|
|
*/
|
|
void add(raw_socket_t const descriptor, short const event = poll_in | poll_error);
|
|
|
|
/**
|
|
* Add a zmq_pollitem_t to the poller; Events to monitor are already configured.
|
|
* If the zmq_pollitem_t has a null socket pointer it is added to the fdindex,
|
|
* otherwise it is added to the socket index.
|
|
*
|
|
* \param item the pollitem to be added
|
|
*/
|
|
void add(zmq_pollitem_t const& item);
|
|
|
|
/**
|
|
* Check if we are monitoring a given socket with this poller.
|
|
*
|
|
* \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 poller.
|
|
*
|
|
* \param descriptor the raw socket to check for.
|
|
* \return true if it is there.
|
|
*/
|
|
bool has(raw_socket_t const descriptor);
|
|
|
|
/**
|
|
* Check if we are monitoring a given pollitem.
|
|
* We assume the pollitem is a socket if it's socket is a non null pointer; otherwise,
|
|
* it is considered as a file descriptor.
|
|
*
|
|
* \param item the pollitem to check for
|
|
* \return true if it is there.
|
|
*/
|
|
bool has(zmq_pollitem_t const& item);
|
|
|
|
/**
|
|
* 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 raw socket to stop monitoring (SOCKET under Windows, a file descriptor otherwise).
|
|
*/
|
|
void remove(raw_socket_t const descriptor);
|
|
|
|
/**
|
|
* Stop monitoring a zmq_pollitem_t
|
|
*
|
|
* \param item the pollitem to stop monitoring.
|
|
*/
|
|
void remove(zmq_pollitem_t const& item);
|
|
|
|
/**
|
|
* 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);
|
|
|
|
/**
|
|
* Update the monitored event flags for a given zmq_pollitem_t
|
|
*
|
|
* \param item the item to change event flags for.
|
|
* \param event the event flags to monitor on the socket.
|
|
*/
|
|
void check_for(zmq_pollitem_t const& item, short const event);
|
|
|
|
/**
|
|
* Poll for monitored events.
|
|
*
|
|
* 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 = 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 the event flags triggered for a zmq_pollitem_t
|
|
*
|
|
* \param item the pollitem to get triggered event flags for.
|
|
* \return the event flags.
|
|
*/
|
|
short events(zmq_pollitem_t const& item) const;
|
|
|
|
/**
|
|
* Check either a standard socket or zmq socket for input events.
|
|
*
|
|
* Templated helper method that calls through to event and checks for a given flag
|
|
*
|
|
* \param watchable either a standard socket or socket known to the poller.
|
|
* \return true if there is input.
|
|
*/
|
|
template<typename Watched>
|
|
bool has_input(Watched const& watchable) const { return (events(watchable) & poll_in) != 0; }
|
|
|
|
/**
|
|
* Check either a standard socket or zmq socket for output events.
|
|
*
|
|
* Templated helper method that calls through to event and checks for a given flag
|
|
*
|
|
* \param watchable either a standard socket or zmq socket known to the poller.
|
|
* \return true if there is output.
|
|
*/
|
|
template<typename Watched>
|
|
bool has_output(Watched const& watchable) const { return (events(watchable) & poll_out) != 0; }
|
|
|
|
/**
|
|
* Check a standard socket (file descriptor or SOCKET).
|
|
*
|
|
* Templated helper method that calls through to event and checks for a given flag
|
|
*
|
|
* Technically this template works for sockets as well but the error flag is never set for
|
|
* sockets so I have no idea why someone would call it.
|
|
*
|
|
* \param watchable a standard socket known to the poller.
|
|
* \return true if there is an error.
|
|
*/
|
|
template<typename Watched>
|
|
bool has_error(Watched const& watchable) const { return (events(watchable) & poll_error) != 0; }
|
|
|
|
private:
|
|
std::vector<zmq_pollitem_t> _items;
|
|
std::unordered_map<void *, size_t> _index;
|
|
std::unordered_map<raw_socket_t, size_t> _fdindex;
|
|
|
|
void reindex(size_t const index);
|
|
};
|
|
|
|
}
|
|
|
|
#endif /* ZMQPP_POLLER_HPP_ */
|