emsApplication/sdk/include/zmqpp/loop.hpp

162 lines
5.0 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.
*/
#pragma once
#include <tuple>
#include <vector>
#include <list>
#include <chrono>
#include <functional>
#include <memory>
#include "compatibility.hpp"
#include "poller.hpp"
namespace zmqpp
{
class socket;
typedef socket socket_t;
/**
* Loop object that helps to manage multiple socket by calling a user-defined handler for each socket
* when a watched event occurs.
* Calls assigned user-defined handler for timed events - repeaded and one-shot.
*
* It uses zmq::poller as the underlying polling mechanism.
*/
class loop
{
public:
/**
* Type used to identify created timers withing loop
*/
typedef void * timer_id_t;
typedef std::function<bool (void) > Callable;
/**
* Construct an empty polling model.
*/
loop();
/**
* Cleanup reactor.
*
* Any sockets will need to be closed separately.
*/
virtual ~loop();
/**
* Add a socket to the loop, 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 loop 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 loop, 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 loop 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);
/**
* Add a timed event to the loop, providing a handler that will be called when timer fires.
*
* \param delay time after which handler will be executed.
* \param times how many times should timer be reneved - 0 for infinte ammount.
* \param callable the function that will be called by the loop after delay.
*/
timer_id_t add(std::chrono::milliseconds delay, size_t times, Callable callable);
/**
* Reset timer in the loop, it will start counting delay time again. Times argument is preserved.
*
* \param timer identifier in the loop.
*/
void reset(timer_id_t const timer);
/**
* Remove timer event from the loop.
*
* \param timer identifier in the loop.
*/
void remove(timer_id_t const timer);
/**
* 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);
/**
* Starts loop. It will block until one of handlers returns false.
*/
void start();
private:
struct timer_t {
size_t times;
std::chrono::milliseconds delay;
std::chrono::steady_clock::time_point when;
timer_t(size_t times, std::chrono::milliseconds delay);
void reset();
void update();
};
typedef std::pair<zmq_pollitem_t, Callable> PollItemCallablePair;
typedef std::pair<std::unique_ptr<timer_t>, Callable> TimerItemCallablePair;
static bool TimerItemCallablePairComp(const TimerItemCallablePair &lhs, const TimerItemCallablePair &rhs);
std::vector<PollItemCallablePair> items_;
std::list<TimerItemCallablePair> timers_;
std::vector<const socket_t *> sockRemoveLater_;
std::vector<raw_socket_t> fdRemoveLater_;
std::vector<timer_id_t> timerRemoveLater_;
void add(const zmq_pollitem_t &item, Callable callable);
void add(std::unique_ptr<timer_t>, Callable callable);
bool start_handle_timers();
bool start_handle_poller();
/**
* Flush the fdRemoveLater_ and sockRemoveLater_ vector, effectively removing
* the item for the reactor and poller.
*/
void flush_remove_later();
/**
* Calculate min time to wait in poller.
*/
long tickless();
poller poller_;
bool dispatching_;
bool rebuild_poller_;
};
}