Tamer
C++ language extensions for event-driven programming
Loading...
Searching...
No Matches
xdriver.hh
1#ifndef TAMER_XDRIVER_HH
2#define TAMER_XDRIVER_HH 1
3/* Copyright (c) 2007-2015, Eddie Kohler
4 * Copyright (c) 2007, Regents of the University of California
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, subject to the conditions
9 * listed in the Tamer LICENSE file. These conditions include: you must
10 * preserve this copyright notice, and you cannot mention the copyright
11 * holders in advertising related to the Software without their permission.
12 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
13 * notice is a summary of the Tamer LICENSE file; the license in that file is
14 * legally binding.
15 */
16#include <tamer/event.hh>
17#include <csignal>
18#include <ctime>
19#include <sys/time.h>
20#include <vector>
21#include <string>
22namespace tamer {
23namespace tamerpriv {
24extern struct timeval recent;
25extern bool need_recent;
26} // namespace tamerpriv
27
28enum loop_flags {
29 loop_default = 0,
30 loop_forever = 0,
31 loop_once = 1
32};
33
34enum signal_flags {
35 signal_default = 0,
36 signal_background = 1
37};
38
39enum fd_actions {
40 fd_read = 0,
41 fd_write = 1, // order matters
42 fd_hangup = 2,
43 nfdactions = 3
44};
45
46class driver : public tamerpriv::simple_driver {
47 public:
48 driver();
49 virtual ~driver();
50
51 enum { capacity = (unsigned) 256 };
52 static inline driver* by_index(unsigned index);
53 inline unsigned index() const;
54
55 // basic functions
56 virtual void at_fd(int fd, int action, event<int> e) = 0;
57 virtual void at_time(const timeval& expiry, event<> e, bool bg) = 0;
58 virtual void at_asap(event<> e) = 0;
59 virtual void at_preblock(event<> e) = 0;
60 virtual void kill_fd(int fd) = 0;
61
62 inline void at_fd(int fd, int action, event<> e);
63 inline void at_time(const timeval& expiry, event<> e);
64 inline void at_time(double expiry, event<> e, bool bg = false);
65 inline void at_delay(timeval delay, event<> e, bool bg = false);
66 void at_delay(double delay, event<> e, bool bg = false);
67 inline void at_delay_sec(int delay, event<> e, bool bg = false);
68 inline void at_delay_msec(int delay, event<> e, bool bg = false);
69 inline void at_delay_usec(int delay, event<> e, bool bg = false);
70
71 static void at_signal(int signo, event<> e,
72 signal_flags flags = signal_default);
73
74 typedef void (*error_handler_type)(int fd, int err, std::string msg);
75 virtual void set_error_handler(error_handler_type errh);
76
77 virtual void loop(loop_flags flag) = 0;
78 virtual void break_loop() = 0;
79 virtual timeval next_wake() const;
80
81 virtual void clear();
82
83 void blocked_locations(std::vector<std::string>& x);
84
85 static driver* make_tamer(int flags);
86 static driver* make_libevent();
87 static driver* make_libev();
88
89 static driver* main;
90
91 static volatile sig_atomic_t sig_any_active;
92 static int sig_pipe[2];
93 static unsigned sig_nforeground;
94 static unsigned sig_ntotal;
95 void dispatch_signals();
96
97private:
98 unsigned index_;
99 std::tuple<int> int_placeholder_;
100
101 static driver* indexed[capacity];
102 static int next_index;
103};
104
105timeval now();
106inline const timeval& recent();
107
108inline driver* driver::by_index(unsigned index) {
109 return index < capacity ? indexed[index] : 0;
110}
111
112inline unsigned driver::index() const {
113 return index_;
114}
115
116inline void driver::at_fd(int fd, int action, event<> e) {
117 at_fd(fd, action, event<int>(e, int_placeholder_));
118}
119
120inline void driver::at_time(const timeval& expiry, event<> e) {
121 at_time(expiry, e, false);
122}
123
124inline void driver::at_time(double expiry, event<> e, bool bg) {
125 timeval tv;
126 tv.tv_sec = (long) expiry;
127 tv.tv_usec = (long) ((expiry - tv.tv_sec) * 1000000);
128 at_time(tv, e, bg);
129}
130
131inline void driver::at_delay(timeval delay, event<> e, bool bg) {
132 timeradd(&delay, &recent(), &delay);
133 at_time(delay, e, bg);
134}
135
136inline void driver::at_delay_sec(int delay, event<> e, bool bg) {
137 if (delay <= 0) {
138 at_asap(e);
139 } else {
140 timeval tv = recent();
141 tv.tv_sec += delay;
142 at_time(tv, e, bg);
143 }
144}
145
146inline void driver::at_delay_msec(int delay, event<> e, bool bg) {
147 if (delay <= 0) {
148 at_asap(e);
149 } else {
150 timeval tv;
151 tv.tv_sec = delay / 1000;
152 tv.tv_usec = (delay % 1000) * 1000;
153 at_delay(tv, e, bg);
154 }
155}
156
157inline void driver::at_delay_usec(int delay, event<> e, bool bg) {
158 if (delay <= 0) {
159 at_asap(e);
160 } else {
161 timeval tv;
162 tv.tv_sec = delay / 1000000;
163 tv.tv_usec = delay % 1000000;
164 at_delay(tv, e, bg);
165 }
166}
167
168namespace tamerpriv {
169inline void blocking_rendezvous::block(closure& c, unsigned position) {
170 block(tamer::driver::main, c, position);
171}
172} // namespace tamerpriv
173} // namespace tamer
174#endif /* TAMER_XDRIVER_HH */
The event template classes and helper functions.
Namespace containing public Tamer classes and functions for the Tamer core.
Definition adapter.hh:17
const timeval & recent()
Return a recent snapshot of the current time.
Definition driver.hh:62
void break_loop()
Exit the current driver loop.
Definition driver.hh:107
void loop()
Run driver loop indefinitely.
Definition driver.hh:97