Permalink
Newer
Older
100644 283 lines (221 sloc) 9.52 KB
1
include::license.txt[]
2
3
:language: C
4
5
Working with an event loop
6
--------------------------
7
8
Running the loop
9
~~~~~~~~~~~~~~~~
10
11
Once you have an event_base with some events registered (see the next section
12
about how to create and register events), you will want Libevent to wait for
13
events and alert you about them.
16
[code,C]
18
#define EVLOOP_ONCE 0x01
19
#define EVLOOP_NONBLOCK 0x02
20
#define EVLOOP_NO_EXIT_ON_EMPTY 0x04
21
22
int event_base_loop(struct event_base *base, int flags);
24
25
By default, the event_base_loop() function 'runs' an event_base until there
26
are no more events registered in it. To run the loop, it repeatedly checks
27
whether any of the registered events has triggered (for example, if a read
28
event's file descriptor is ready to read, or if a timeout event's timeout is
29
ready to expire). Once this happens, it marks all triggered events as
30
"active", and starts to run them.
31
32
You can change the behavior of event_base_loop() by setting one or more flags
33
in its 'flags' argument. If EVLOOP_ONCE is set, then the loop will wait
34
until some events become active, then run active events until there are no
35
more to run, then return. If EVLOOP_NONBLOCK is set, then
36
the loop will not wait for events to trigger: it will only check whether
37
any events are ready to trigger immediately, and run their callbacks if so.
39
Ordinarily, the loop will exit as soon as it has no pending events. You can
40
override this behavior by passing the EVLOOP_NO_EXIT_ON_EMPTY flag---for
41
example, if you're going to be adding events from some other thread. If you
@mistotebe
Jul 4, 2012
42
do set EVLOOP_NO_EXIT_ON_EMPTY, the loop will keep running until somebody
43
calls event_base_loopbreak(), or calls event_base_loopexit(), or an error
44
occurs.
45
46
When it is done, event_base_loop() returns 0 if it exited normally, and -1 if
47
it exited because of some unhandled error in the backend.
48
49
To aid in understanding, here's an approximate summary of the event_base_loop
50
algorithm:
51
52
.Pseudocode
53
[code,C]
55
while (any events are registered with the loop,
56
or EVLOOP_NO_EXIT_ON_EMPTY was set) {
57
58
if (EVLOOP_NONBLOCK was set, or any events are already active)
59
If any registered events have triggered, mark them active.
60
else
61
Wait until at least one event has triggered, and mark it active.
62
63
for (p = 0; p < n_priorities; ++p {
64
if (any event with priority of p is active) {
65
Run all active events with priority of p.
66
break; /* Do not run any events of a less important priority */
67
}
68
}
69
70
if (EVLOOP_ONCE was set or EVLOOP_NONBLOCK was set)
71
break;
72
}
74
75
As a convenience, you can also call:
76
77
.Interface
78
[code,C]
80
int event_base_dispatch(struct event_base *base);
82
83
The event_base_dispatch() call is the same as event_base_loop(), with no
84
flags set. Thus, it keeps running until there are no more registered events
85
or until event_base_loopbreak() or event_base_loopexit() is called.
86
87
These functions are defined in <event2/event.h>. They have existed since
88
Libevent 1.0.
89
90
Stopping the loop
91
~~~~~~~~~~~~~~~~~
92
93
If you want an active event loop to stop running before all events are
94
removed from it, you have two slightly different functions you can call.
95
96
.Interface
97
[code,C]
99
int event_base_loopexit(struct event_base *base,
100
const struct timeval *tv);
101
int event_base_loopbreak(struct event_base *base);
103
104
The event_base_loopexit() function tells an event_base to stop looping after
105
a given time has elapsed. If the 'tv' argument is NULL, the event_base stops
106
looping without a delay. If the event_base is currently running callbacks
107
for any active
108
events, it will continue running them, and not exit until they have all been
109
run.
110
111
The event_base_loopbreak() function tells the event_base to exit its loop
112
immediately. It differs from event_base_loopexit(base, NULL) in that if
113
the event_base is currently running callbacks for any active events, it will
114
exit
115
immediately after finishing the one it's currently processing.
116
117
Note also that event_base_loopexit(base,NULL) and event_base_loopbreak(base)
118
act differently when no event loop is running: loopexit schedules the next
119
instance of the event loop to stop right after the next round of callbacks
120
are run (as if it had been invoked with EVLOOP_ONCE) whereas loopbreak only
121
stops a currently running loop, and has no effect if the event loop isn't
122
running.
123
124
Both of these methods return 0 on success and -1 on failure.
125
126
.Example: Shut down immediately
127
[code,C]
129
#include <event2/event.h>
130
131
/* Here's a callback function that calls loopbreak */
132
void cb(int sock, short what, void *arg)
133
{
134
struct event_base *base = arg;
135
event_base_loopbreak(base);
136
}
137
138
void main_loop(struct event_base *base, evutil_socket_t watchdog_fd)
139
{
140
struct event *watchdog_event;
141
142
/* Construct a new event to trigger whenever there are any bytes to
143
read from a watchdog socket. When that happens, we'll call the
144
cb function, which will make the loop exit immediately without
145
running any other active events at all.
146
*/
147
watchdog_event = event_new(base, watchdog_fd, EV_READ, cb, base);
148
149
event_add(watchdog_event, NULL);
150
151
event_base_dispatch(base);
152
}
154
155
.Example: Run an event loop for 10 seconds, then exit.
156
[code,C]
158
#include <event2/event.h>
160
void run_base_with_ticks(struct event_base *base)
161
{
162
struct timeval ten_sec;
164
ten_sec.tv_sec = 10;
165
ten_sec.tv_usec = 0;
167
/* Now we run the event_base for a series of 10-second intervals, printing
168
"Tick" after each. For a much better way to implement a 10-second
169
timer, see the section below about persistent timer events. */
170
while (1) {
171
/* This schedules an exit ten seconds from now. */
172
event_base_loopexit(base, &ten_sec);
174
event_base_dispatch(base);
175
puts("Tick");
176
}
177
}
180
Sometimes you may want to tell whether your call to event_base_dispatch() or
181
event_base_loop() exited normally, or because of a call to
182
event_base_loopexit() or event_base_break(). You can use these functions to
183
tell whether loopexit or break was called:
184
185
.Interface
186
[code,C]
187
--------
188
int event_base_got_exit(struct event_base *base);
189
int event_base_got_break(struct event_base *base);
190
--------
191
192
These two functions will return true if the loop was stopped with
193
event_base_loopexit() or event_base_break() respectively, and false
194
otherwise. Their values will be reset the next time you start the event
195
loop.
196
197
These functions are declared in <event2/event.h>. The event_break_loopexit()
198
function was first implemented in Libevent 1.0c; event_break_loopbreak() was
199
first implemented in Libevent 1.4.3.
201
Checking the internal time cache
202
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
203
204
Sometimes you want to get an approximate view of the current time inside
205
an event callback, and you want to get it without calling gettimeofday()
206
yourself (presumably because your OS implements gettimeofday() as a
207
syscall, and you're trying to avoid syscall overhead).
208
209
From within a callback, you can ask Libevent for its view of the current
210
time when it began executing this round of callbacks:
211
212
.Interface
213
[code,C]
214
-----
215
int event_base_gettimeofday_cached(struct event_base *base,
216
struct timeval *tv_out);
217
-----
218
219
The event_base_gettimeofday_cached() function sets the value of its
220
'tv_out' argument to the cached time if the event_base is currently
221
executing callbacks. Otherwise, it calls evutil_gettimeofday() for the
222
actual current time. It returns 0 on success, and negative on failure.
223
224
Note that since the timeval is cached when Libevent starts running
225
callbacks, it will be at least a little inaccurate. If your callbacks
226
take a long time to run, it may be *very* inaccurate. To force an immediate
227
cache update, you can call this function:
228
229
.Interface
230
[code,C]
231
-----
232
int event_base_update_cache_time(struct event_base *base);
233
-----
234
235
It returns 0 on success and -1 on failure, and has no effect if the base was
236
not running its event loop.
237
238
The event_base_gettimeofday_cached() function was new in Libevent
239
2.0.4-alpha. Libevent 2.1.1-alpha added event_base_update_cache_time().
242
Dumping the event_base status
243
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
244
245
.Interface
246
[code,C]
247
--------
248
void event_base_dump_events(struct event_base *base, FILE *f);
249
--------
250
251
For help debugging your program (or debugging Libevent!) you might sometimes
252
want a complete list of all events added in the event_base and their status.
253
Calling event_base_dump_events() writes this list to the stdio file provided.
254
255
The list is meant to be human-readable; its format *will* change in future
256
versions of Libevent.
257
258
This function was introduced in Libevent 2.0.1-alpha.
260
Obsolete event loop functions
261
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
262
263
As discussed above, older versions of Libevent APIs had a global
264
notion of a "current" event_base.
265
266
Some of the event loop functions in this section had variants that
267
operated on the current base. These functions behaved as the current
268
functions, except that they took no base argument.
269
270
[options="header",width="85%"]
271
|======================================================================
272
| Current function | Obsolete current-base version
273
| event_base_dispatch() | event_dispatch()
274
| event_base_loop() | event_loop()
275
| event_base_loopexit() | event_loopexit()
276
| event_base_loopbreak() | event_loopbreak()
277
|======================================================================
278
279
NOTE: Because event_base did not support locking before Libevent 2.0,
280
these functions weren't completely threadsafe: it was not permissible
281
to call the _loopbreak() or _loopexit() functions from a thread other
282
than the one executing the event loop.