2018-04-30 13:18:57 +00:00
|
|
|
#ifndef LLARP_EV_HPP
|
|
|
|
#define LLARP_EV_HPP
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2019-02-02 23:12:42 +00:00
|
|
|
#include <util/buffer.hpp>
|
2021-03-02 02:06:20 +00:00
|
|
|
#include <util/time.hpp>
|
2019-09-01 13:26:16 +00:00
|
|
|
#include <util/thread/threading.hpp>
|
2021-03-02 02:06:20 +00:00
|
|
|
#include <constants/evloop.hpp>
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2018-10-01 02:08:03 +00:00
|
|
|
// writev
|
|
|
|
#ifndef _WIN32
|
2018-09-30 13:23:37 +00:00
|
|
|
#include <sys/uio.h>
|
2019-04-19 18:24:33 +00:00
|
|
|
#include <unistd.h>
|
2018-10-01 02:08:03 +00:00
|
|
|
#endif
|
2018-12-12 02:52:51 +00:00
|
|
|
|
2018-11-02 12:35:20 +00:00
|
|
|
#include <algorithm>
|
2018-12-12 02:52:51 +00:00
|
|
|
#include <deque>
|
|
|
|
#include <list>
|
2019-03-03 20:51:47 +00:00
|
|
|
#include <future>
|
2019-07-30 23:42:13 +00:00
|
|
|
#include <utility>
|
2018-10-04 11:20:08 +00:00
|
|
|
|
|
|
|
#ifdef _WIN32
|
2018-12-13 23:02:41 +00:00
|
|
|
// From the preview SDK, should take a look at that
|
|
|
|
// periodically in case its definition changes
|
|
|
|
#define UNIX_PATH_MAX 108
|
|
|
|
|
|
|
|
typedef struct sockaddr_un
|
2018-11-26 17:10:18 +00:00
|
|
|
{
|
2018-12-13 23:02:41 +00:00
|
|
|
ADDRESS_FAMILY sun_family; /* AF_UNIX */
|
|
|
|
char sun_path[UNIX_PATH_MAX]; /* pathname */
|
|
|
|
} SOCKADDR_UN, *PSOCKADDR_UN;
|
2018-12-03 20:37:25 +00:00
|
|
|
#else
|
2018-12-04 23:45:08 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || (__APPLE__ && __MACH__)
|
2018-12-04 23:45:08 +00:00
|
|
|
#include <sys/event.h>
|
|
|
|
#endif
|
|
|
|
|
2018-12-03 20:37:25 +00:00
|
|
|
#include <sys/un.h>
|
2018-10-04 11:20:08 +00:00
|
|
|
#endif
|
|
|
|
|
2019-08-22 11:18:05 +00:00
|
|
|
struct llarp_ev_pkt_pipe;
|
|
|
|
|
2018-08-15 15:36:34 +00:00
|
|
|
#ifndef MAX_WRITE_QUEUE_SIZE
|
2018-11-09 14:48:43 +00:00
|
|
|
#define MAX_WRITE_QUEUE_SIZE (1024UL)
|
2018-08-15 15:36:34 +00:00
|
|
|
#endif
|
2018-04-30 13:18:57 +00:00
|
|
|
|
2018-09-06 20:31:58 +00:00
|
|
|
#ifndef EV_READ_BUF_SZ
|
2018-11-09 14:48:43 +00:00
|
|
|
#define EV_READ_BUF_SZ (4 * 1024UL)
|
2018-09-06 20:31:58 +00:00
|
|
|
#endif
|
2018-10-27 18:26:08 +00:00
|
|
|
#ifndef EV_WRITE_BUF_SZ
|
2020-01-07 11:59:17 +00:00
|
|
|
#define EV_WRITE_BUF_SZ (4 * 1024UL)
|
2018-10-27 18:26:08 +00:00
|
|
|
#endif
|
2018-09-06 20:31:58 +00:00
|
|
|
|
2018-05-22 15:54:19 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
2021-03-02 02:06:20 +00:00
|
|
|
class Logic;
|
|
|
|
struct SockAddr;
|
|
|
|
struct UDPHandle;
|
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
namespace vpn
|
2018-10-29 16:48:36 +00:00
|
|
|
{
|
2021-01-11 23:13:22 +00:00
|
|
|
class NetworkInterface;
|
|
|
|
}
|
2018-11-19 07:55:19 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
namespace net
|
2021-02-22 13:26:32 +00:00
|
|
|
{
|
2021-03-02 02:06:20 +00:00
|
|
|
struct IPPacket;
|
|
|
|
}
|
2021-02-22 13:26:32 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
/// distinct event loop waker upper; used to idempotently schedule a task on the next event loop
|
|
|
|
///
|
|
|
|
/// Created via EventLoop::make_waker(...).
|
|
|
|
class EventLoopWakeup
|
|
|
|
{
|
2021-02-22 13:26:32 +00:00
|
|
|
public:
|
2021-03-02 02:06:20 +00:00
|
|
|
/// Destructor: remove the task from the event loop task. (Note that destruction here only
|
|
|
|
/// initiates removal of the task from the underlying event loop: it is *possible* for the
|
|
|
|
/// callback to fire again if already triggered depending on the underlying implementation).
|
2021-02-22 13:26:32 +00:00
|
|
|
virtual ~EventLoopWakeup() = default;
|
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
/// trigger this task to run on the next event loop iteration; does nothing if already
|
|
|
|
/// triggered.
|
2021-02-22 13:26:32 +00:00
|
|
|
virtual void
|
2021-03-02 02:06:20 +00:00
|
|
|
Trigger() = 0;
|
|
|
|
};
|
2021-02-22 13:26:32 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
/// holds a repeated task on the event loop; the task is removed on destruction
|
|
|
|
class EventLoopRepeater
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Destructor: if the task has been started then it is removed from the event loop. Note
|
|
|
|
// that it is possible for a task to fire *after* destruction of this container;
|
|
|
|
// destruction only initiates removal of the periodic task.
|
|
|
|
virtual ~EventLoopRepeater() = default;
|
|
|
|
|
|
|
|
// Starts the repeater to call `task` every `every` period.
|
2021-02-22 13:26:32 +00:00
|
|
|
virtual void
|
2021-03-02 02:06:20 +00:00
|
|
|
start(llarp_time_t every, std::function<void()> task) = 0;
|
2021-02-22 13:26:32 +00:00
|
|
|
};
|
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
// this (nearly!) abstract base class
|
|
|
|
// is overriden for each platform
|
|
|
|
struct EventLoop
|
2021-03-02 02:06:20 +00:00
|
|
|
// : std::enable_shared_from_this<EventLoop> // FIXME: do I actually need shared_from_this()?
|
2021-01-11 23:13:22 +00:00
|
|
|
{
|
2021-03-02 02:06:20 +00:00
|
|
|
// Runs the event loop. This does not return until sometime after `stop()` is called (and so
|
|
|
|
// typically you want to run this in its own thread).
|
|
|
|
void
|
|
|
|
run(Logic& logic);
|
2018-10-24 18:02:42 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
// Actually runs the underlying implementation event loop; called by run().
|
|
|
|
virtual void
|
|
|
|
run_loop() = 0;
|
2018-10-24 18:02:42 +00:00
|
|
|
|
2018-10-25 12:39:32 +00:00
|
|
|
virtual bool
|
2021-01-11 23:13:22 +00:00
|
|
|
running() const = 0;
|
2018-10-24 18:02:42 +00:00
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
virtual llarp_time_t
|
|
|
|
time_now() const
|
2018-10-24 18:02:42 +00:00
|
|
|
{
|
2021-01-11 23:13:22 +00:00
|
|
|
return llarp::time_now_ms();
|
2018-10-24 18:02:42 +00:00
|
|
|
}
|
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
virtual void
|
2021-03-02 02:06:20 +00:00
|
|
|
stopped()
|
|
|
|
{}
|
2018-11-02 12:35:20 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
// Adds a timer to the event loop; should only be called from the logic thread (and so is
|
|
|
|
// typically scheduled via a call to Logic::call_later()).
|
2021-01-11 23:13:22 +00:00
|
|
|
virtual void
|
2021-03-02 02:06:20 +00:00
|
|
|
call_after_delay(llarp_time_t delay_ms, std::function<void(void)> callback) = 0;
|
2018-10-25 12:00:29 +00:00
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
virtual bool
|
|
|
|
add_network_interface(
|
|
|
|
std::shared_ptr<vpn::NetworkInterface> netif,
|
|
|
|
std::function<void(net::IPPacket)> packetHandler) = 0;
|
2018-10-25 13:40:07 +00:00
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
virtual bool
|
|
|
|
add_ticker(std::function<void(void)> ticker) = 0;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2018-11-01 12:47:14 +00:00
|
|
|
virtual void
|
2021-01-11 23:13:22 +00:00
|
|
|
stop() = 0;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
using UDPReceiveFunc = std::function<void(UDPHandle&, SockAddr src, llarp::OwnedBuffer buf)>;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
// Constructs a UDP socket that can be used for sending and/or receiving
|
|
|
|
virtual std::shared_ptr<UDPHandle>
|
|
|
|
udp(UDPReceiveFunc on_recv) = 0;
|
2018-10-25 12:00:29 +00:00
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
/// give this event loop a logic thread for calling
|
2021-03-02 02:06:20 +00:00
|
|
|
virtual void
|
|
|
|
set_logic(const std::shared_ptr<llarp::Logic>& logic) = 0;
|
2019-07-06 17:03:40 +00:00
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
virtual ~EventLoop() = default;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2018-11-02 12:35:20 +00:00
|
|
|
virtual void
|
2021-01-11 23:13:22 +00:00
|
|
|
call_soon(std::function<void(void)> f) = 0;
|
2018-11-02 12:35:20 +00:00
|
|
|
|
2021-01-11 23:13:22 +00:00
|
|
|
/// set the function that is called once per cycle the flush all the queues
|
2018-12-14 15:43:44 +00:00
|
|
|
virtual void
|
2021-01-11 23:13:22 +00:00
|
|
|
set_pump_function(std::function<void(void)> pumpll) = 0;
|
2018-12-14 15:43:44 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
/// Make a thread-safe event loop waker (an "async" in libuv terminology) on this event loop;
|
|
|
|
/// you can call `->Trigger()` on the returned shared pointer to fire the callback at the next
|
|
|
|
/// available event loop iteration. (Multiple Trigger calls invoked before the call is actually
|
|
|
|
/// made are coalesced into one call).
|
|
|
|
virtual std::shared_ptr<EventLoopWakeup>
|
|
|
|
make_waker(std::function<void()> callback) = 0;
|
2018-10-29 23:56:05 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
// Initializes a new repeated task object. Note that the task is not actually added to the event
|
|
|
|
// loop until you call start() on the returned object. Typically invoked via Logic::call_every.
|
|
|
|
virtual std::shared_ptr<EventLoopRepeater>
|
|
|
|
make_repeater() = 0;
|
|
|
|
|
|
|
|
// Constructs and initializes a new default (libuv) event loop
|
|
|
|
static std::shared_ptr<EventLoop>
|
|
|
|
create(size_t queueLength = event_loop_queue_size);
|
2021-02-22 13:26:32 +00:00
|
|
|
|
2021-03-02 02:06:20 +00:00
|
|
|
// Returns true if called from within the event loop thread, false otherwise.
|
|
|
|
virtual bool
|
|
|
|
inEventLoopThread() const = 0;
|
2018-10-25 12:00:29 +00:00
|
|
|
};
|
2021-03-02 02:06:20 +00:00
|
|
|
|
|
|
|
using EventLoop_ptr = std::shared_ptr<EventLoop>;
|
|
|
|
|
2019-04-25 23:21:19 +00:00
|
|
|
} // namespace llarp
|
2018-04-30 13:18:57 +00:00
|
|
|
#endif
|