libfilezilla
event_loop.hpp
Go to the documentation of this file.
1 #ifndef LIBFILEZILLA_EVENT_LOOP_HEADER
2 #define LIBFILEZILLA_EVENT_LOOP_HEADER
3 
4 #include "apply.hpp"
5 #include "event.hpp"
6 #include "mutex.hpp"
7 #include "time.hpp"
8 #include "thread.hpp"
9 
10 #include <deque>
11 #include <functional>
12 #include <memory>
13 #include <vector>
14 
19 namespace fz {
20 
21 class async_task;
22 class event_handler;
23 class thread_pool;
24 
33 class FZ_PUBLIC_SYMBOL event_loop final
34 {
35 public:
37  event_loop();
38 
40  explicit event_loop(thread_pool & pool);
41 
42  enum loop_option
43  {
44  threadless
45  };
46  explicit event_loop(loop_option);
47 
49  ~event_loop();
50 
51  event_loop(event_loop const&) = delete;
52  event_loop& operator=(event_loop const&) = delete;
53 
65  void filter_events(std::function<bool (event_handler*&, event_base&)> const& filter);
66 
73  void stop(bool join = false);
74 
76  void run();
77 
78  bool running() const;
79 
80  void resend_current_event() {
81  resend_ = true;
82  }
83 
84 private:
85  friend class event_handler;
86 
87  void FZ_PRIVATE_SYMBOL remove_handler(event_handler* handler);
88 
89  timer_id FZ_PRIVATE_SYMBOL add_timer(event_handler* handler, monotonic_clock const& deadline, duration const& interval);
90  void FZ_PRIVATE_SYMBOL stop_timer(timer_id id);
91  timer_id FZ_PRIVATE_SYMBOL stop_add_timer(timer_id id, event_handler* handler, monotonic_clock const& deadline, duration const& interval);
92 
93  void send_event(event_handler* handler, event_base* evt, bool deletable);
94 
95  // Process the next (if any) event. Returns true if an event has been processed
96  bool FZ_PRIVATE_SYMBOL process_event(scoped_lock & l);
97 
98  // Process timers. Returns true if a timer has been triggered
99  bool FZ_PRIVATE_SYMBOL process_timers(scoped_lock & l, monotonic_clock& now);
100 
101  void FZ_PRIVATE_SYMBOL entry();
102  void FZ_PRIVATE_SYMBOL timer_entry();
103 
104  struct FZ_PRIVATE_SYMBOL timer_data final
105  {
106  event_handler* handler_{};
107  timer_id id_{};
108  monotonic_clock deadline_;
109  duration interval_{};
110  };
111 
112  timer_id FZ_PRIVATE_SYMBOL setup_timer(scoped_lock &lock, timer_data &d, event_handler* handler, monotonic_clock const& deadline, duration const& interval);
113 
114  typedef std::vector<timer_data> Timers;
115 
116  typedef std::deque<std::tuple<event_handler*, event_base*, bool>> Events;
117  Events pending_events_;
118  Timers timers_;
119 
120  mutable mutex sync_;
121  condition cond_;
122 
123  condition timer_cond_;
124  bool do_timers_{};
125 
126  event_handler * active_handler_{};
127 
128  monotonic_clock deadline_;
129 
130  timer_id next_timer_id_{};
131 
132  thread::id thread_id_{};
133 
134  std::unique_ptr<thread> thread_;
135  std::unique_ptr<async_task> task_;
136 
137  std::unique_ptr<thread> timer_thread_;
138  std::unique_ptr<async_task> timer_task_;
139 
140  bool quit_{};
141  bool threadless_{};
142  bool resend_{};
143 };
144 
145 }
146 #endif
Thread synchronization primitives: mutex, scoped_lock and condition.
A simple scoped lock.
Definition: mutex.hpp:92
simple_event< process_event_type, process *, process_event_flag > process_event
Definition: process.hpp:37
Simple handler for asynchronous event processing.
Definition: event_handler.hpp:54
Waitable condition variable.
Definition: mutex.hpp:195
Assorted classes dealing with time.
A threaded event loop that supports sending events and timers.
Definition: event_loop.hpp:33
Declares thread.
A monotonic clock (aka steady clock) is independent from walltime.
Definition: time.hpp:402
The namespace used by libfilezilla.
Definition: apply.hpp:17
The duration class represents a time interval in milliseconds.
Definition: time.hpp:290
Declares event_base and simple_event<>
Template helper to call a function with its arguments extracted from a tuple.
Lean replacement for std::(recursive_)mutex.
Definition: mutex.hpp:51
A dumb thread-pool for asynchronous tasks.
Definition: thread_pool.hpp:63
Common base class for all events.
Definition: event.hpp:22