-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathEventLoop.cc
More file actions
89 lines (69 loc) · 2.31 KB
/
EventLoop.cc
File metadata and controls
89 lines (69 loc) · 2.31 KB
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "EventLoop.hh"
#include <stdlib.h>
#include <event2/event.h>
namespace fluid_base {
// Define our own value, since the stdint.h define doesn't work in C++
#define OF_MAX_LEN 0xFFFF
// See FIXME in EventLoop::EventLoop
#ifndef EVLOOP_NO_EXIT_ON_EMPTY
extern "C" void event_base_add_virtual(struct event_base *);
extern "C" void event_base_del_virtual(struct event_base *);
#endif
class EventLoop::LibEventEventLoop {
private:
friend class EventLoop;
struct event_base *base;
};
EventLoop::EventLoop(int id) {
this->id = id;
this->m_implementation = new EventLoop::LibEventEventLoop;
this->m_implementation->base = event_base_new();
this->stopped = false;
if (!this->m_implementation->base) {
fprintf(stderr, "Error creating EventLoop %d\n", id);
exit(EXIT_FAILURE);
}
/* FIXME: dirty hack warning!
We add a virtual event to prevent the loop from exiting when there are
no events.
This fix is needed because libevent 2.0 doesn't have the flag
EVLOOP_NO_EXIT_ON_EMPTY. Version 2.1 fixes this, so this will have to
be changed in the future (to make it prettier and to avoid breaking
anything).
See:
http://stackoverflow.com/questions/7645217/user-triggered-event-in-libevent
*/
#ifndef EVLOOP_NO_EXIT_ON_EMPTY
event_base_add_virtual(this->m_implementation->base);
#endif
}
EventLoop::~EventLoop() {
event_base_free(this->m_implementation->base);
delete this->m_implementation;
}
void EventLoop::run() {
// Only run if EventLoop::stop hasn't been called first
if (stopped) return;
event_base_dispatch(this->m_implementation->base);
// See note in EventLoop::EventLoop. Here we disable the virtual event
// to guarantee that nothing blocks.
#ifndef EVLOOP_NO_EXIT_ON_EMPTY
event_base_del_virtual(this->m_implementation->base);
event_base_loop(this->m_implementation->base, EVLOOP_NONBLOCK);
#else
event_base_loop(this->m_implementation->base, EVLOOP_NO_EXIT_ON_EMPTY);
#endif
}
void EventLoop::stop() {
// Prevent run from running if it's not started :)
this->stopped = true;
event_base_loopbreak(this->m_implementation->base);
}
void* EventLoop::thread_adapter(void* arg) {
((EventLoop*) arg)->run();
return NULL;
}
void* EventLoop::get_base() {
return this->m_implementation->base;
}
}