emsApplication/sdk/include/zmqpp/poller.hpp

245 lines
6.8 KiB
C++
Raw Normal View History

2024-05-24 12:29:09 +08:00
/*
* 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_ */