aboutsummaryrefslogtreecommitdiff
path: root/src/AsyncEventLoop.hpp
blob: 7a3ed69af5f1825ef31c41b1b6b36e27d767ea98 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#pragma once

#include <atomic>
#include <functional>
#include <mutex>
#include <queue>
#include <thread>
#include <utility>
#include <uv.h>

#include "utils.hpp"

class AsyncEventLoop {
public:
  AsyncEventLoop();
  ~AsyncEventLoop();

  void wake();
  DEFINE_GETTER(get_uv_loop, loop)

  template <typename F> void queue_task(F &&task) {
    {
      const std::lock_guard<std::mutex> lock(tasks_queue_mutex);
      tasks_queue.push(std::forward<F>(task));
    }
    wake();
  }

protected:
  void run_loop();
  void process_tasks();
  void flush_tasks();
  static void async_handle_callback(uv_async_t *handle);
  static void close_handle(uv_handle_t *handle, void *arg = nullptr);

private:
  uv_loop_t *loop;
  std::thread loop_thread;
  uv_async_t async_handle;
  std::atomic<bool> is_loop_running = false;
  std::queue<std::function<void()>> tasks_queue;
  std::mutex tasks_queue_mutex;
};