The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
event.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/** Wrapper around libkqueue to make managing events easier
19 *
20 * @file src/lib/util/event.h
21 *
22 * @copyright 2007 The FreeRADIUS server project
23 * @copyright 2007 Alan DeKok (aland@deployingradius.com)
24 */
25RCSIDH(event_h, "$Id: d3c470a5e7ce5cca84f06a66c28e916759187ee3 $")
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#include <freeradius-devel/build.h>
32#include <freeradius-devel/missing.h>
33#include <freeradius-devel/util/time.h>
34#include <freeradius-devel/util/talloc.h>
35
36#include <stdbool.h>
37#include <sys/event.h>
38
39/** An opaque file descriptor handle
40 */
42
43/** An opaque event list handle
44 */
46
47/** An opaque timer handle
48 */
50
51/** An opaque PID status handle
52 */
54
55/** An opaquer user event handle
56 */
58
59/** The type of filter to install for an FD
60 */
61typedef enum {
62 FR_EVENT_FILTER_IO = 1, //!< Combined filter for read/write functions/
63 FR_EVENT_FILTER_VNODE //!< Filter for vnode subfilters
65
66/** Operations to perform on filter
67 */
68typedef enum {
69 FR_EVENT_OP_SUSPEND = 1, //!< Temporarily remove the relevant filter from kevent.
70 FR_EVENT_OP_RESUME //!< Reinsert the filter into kevent.
72
73/** Structure describing a modification to a filter's state
74 */
75typedef struct {
76 size_t offset; //!< Offset of function in func struct.
77 fr_event_op_t op; //!< Operation to perform on function/filter.
79
80/** Temporarily remove the filter for a func from kevent
81 *
82 * Use to populate elements in an array of #fr_event_update_t.
83 *
84 @code {.c}
85 static fr_event_update_t pause_read[] = {
86 FR_EVENT_SUSPEND(fr_event_io_func_t, read),
87 { 0 }
88 }
89 @endcode
90 *
91 * @param[in] _s the structure containing the func to suspend.
92 * @param[in] _f the func to suspend.
93 */
94#define FR_EVENT_SUSPEND(_s, _f) { .offset = offsetof(_s, _f), .op = FR_EVENT_OP_SUSPEND }
95
96/** Re-add the filter for a func from kevent
97 *
98 * Use to populate elements in an array of #fr_event_update_t.
99 *
100 @code {.c}
101 static fr_event_update_t resume_read[] = {
102 FR_EVENT_RESUME(fr_event_io_func_t, read),
103 { 0 }
104 }
105 @endcode
106 *
107 * @param[in] _s the structure containing the func to suspend.
108 * @param[in] _f the func to resume.
109 */
110#define FR_EVENT_RESUME(_s, _f) { .offset = offsetof(_s, _f), .op = FR_EVENT_OP_RESUME }
111
112/** Called when a timer event fires
113 *
114 * @param[in] now The current time.
115 * @param[in] el Event list the timer event was inserted into.
116 * @param[in] uctx User ctx passed to #fr_event_timer_in or #fr_event_timer_at.
117 */
118typedef void (*fr_event_timer_cb_t)(fr_event_list_t *el, fr_time_t now, void *uctx);
119
120/** Called after each event loop cycle
121 *
122 * Called before calling kqueue to put the thread in a sleeping state.
123 *
124 * @param[in] now The current time.
125 * @param[in] wake When we'll next need to wake up to service an event.
126 * @param[in] uctx User ctx passed to #fr_event_list_alloc.
127 */
128typedef int (*fr_event_status_cb_t)(fr_time_t now, fr_time_delta_t wake, void *uctx);
129
130/** Called when an IO event occurs on a file descriptor
131 *
132 * @param[in] el Event list the file descriptor was inserted into.
133 * @param[in] fd That experienced the IO event.
134 * @param[in] flags field as returned by kevent.
135 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
136 */
137typedef void (*fr_event_fd_cb_t)(fr_event_list_t *el, int fd, int flags, void *uctx);
138
139/** Called when an IO error event occurs on a file descriptor
140 *
141 * @param[in] el Event list the file descriptor was inserted into.
142 * @param[in] fd That experienced the IO event.
143 * @param[in] flags field as returned by kevent.
144 * @param[in] fd_errno File descriptor error.
145 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
146 */
147typedef void (*fr_event_error_cb_t)(fr_event_list_t *el, int fd, int flags, int fd_errno, void *uctx);
148
149/** Called when a child process has exited
150 *
151 * @param[in] el Event list
152 * @param[in] pid That exited
153 * @param[in] status exit status
154 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
155 */
156typedef void (*fr_event_pid_cb_t)(fr_event_list_t *el, pid_t pid, int status, void *uctx);
157
158/** Called when a user kevent occurs
159 *
160 * @param[in] el Event list
161 * @param[in] uctx User ctx passed to #fr_event_user_insert.
162 */
163typedef void (*fr_event_user_cb_t)(fr_event_list_t *el, void *uctx);
164
165/** Alternative time source, useful for testing
166 *
167 * @return the current time in nanoseconds past the epoch.
168 */
170
171/** Callbacks for the #FR_EVENT_FILTER_IO filter
172 */
173typedef struct {
174 fr_event_fd_cb_t read; //!< Callback for when data is available.
175 fr_event_fd_cb_t write; //!< Callback for when we can write data.
177
178/** Callbacks for the #FR_EVENT_FILTER_VNODE filter
179 */
180typedef struct {
181 fr_event_fd_cb_t delete; //!< The file was deleted.
182 fr_event_fd_cb_t write; //!< The file was written to.
183 fr_event_fd_cb_t extend; //!< Additional files were added to a directory.
184 fr_event_fd_cb_t attrib; //!< File attributes changed.
185 fr_event_fd_cb_t link; //!< The link count on the file changed.
186 fr_event_fd_cb_t rename; //!< The file was renamed.
187#ifdef NOTE_REVOKE
188 fr_event_fd_cb_t revoke; //!< Volume containing the file was unmounted or
189 ///< access was revoked with revoke().
190#endif
191#ifdef NOTE_FUNLOCK
192 fr_event_fd_cb_t funlock; //!< The file was unlocked.
193#endif
195
196/** Union of all filter functions
197 */
198typedef union {
199 fr_event_io_func_t io; //!< Read/write functions.
200 fr_event_vnode_func_t vnode; //!< vnode callback functions.
202
207
209 fr_event_list_t *dst, fr_event_list_t *src, int fd, fr_event_filter_t filter);
210#define fr_event_fd_mode(...) _fr_event_fd_move(NDEBUG_LOCATION_EXP __VA_ARGS__)
211
213 TALLOC_CTX *ctx, fr_event_fd_t **ef_out,
214 fr_event_list_t *el, int fd,
215 fr_event_filter_t filter,
216 void *funcs,
218 void *uctx);
219#define fr_event_filter_insert(...) _fr_event_filter_insert(NDEBUG_LOCATION_EXP __VA_ARGS__)
220
222 fr_event_list_t *el, int fd, fr_event_filter_t filter,
223 fr_event_update_t const updates[]);
224#define fr_event_filter_update(...) _fr_event_filter_update(NDEBUG_LOCATION_EXP __VA_ARGS__)
225
227 TALLOC_CTX *ctx, fr_event_fd_t **ef_out, fr_event_list_t *el, int fd,
228 fr_event_fd_cb_t read_fn,
229 fr_event_fd_cb_t write_fn,
231 void *uctx);
232#define fr_event_fd_insert(...) _fr_event_fd_insert(NDEBUG_LOCATION_EXP __VA_ARGS__)
233
235
237
238fr_event_fd_cb_t fr_event_fd_cb(fr_event_fd_t *ef, int filter, int fflags);
239
241
242#ifndef NDEBUG
243int fr_event_fd_armour(fr_event_list_t *el, int fd, fr_event_filter_t, uintptr_t armour);
244int fr_event_fd_unarmour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uintptr_t armour);
245#endif
246
248 TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_timer_t const **ev,
249 fr_time_t when, fr_event_timer_cb_t callback, void const *uctx);
250#define fr_event_timer_at(...) _fr_event_timer_at(NDEBUG_LOCATION_EXP __VA_ARGS__)
251
253 TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_timer_t const **ev,
254 fr_time_delta_t delta, fr_event_timer_cb_t callback, void const *uctx);
255#define fr_event_timer_in(...) _fr_event_timer_in(NDEBUG_LOCATION_EXP __VA_ARGS__)
256
258
260
262 TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_pid_t const **ev_p,
263 pid_t pid, fr_event_pid_cb_t wait_fn, void *uctx)
264 CC_HINT(nonnull(NDEBUG_LOCATION_NONNULL(2)));
265#define fr_event_pid_wait(...) _fr_event_pid_wait(NDEBUG_LOCATION_EXP __VA_ARGS__)
266
268 fr_event_list_t *el, pid_t pid,
269 fr_event_pid_cb_t wait_fn, void *uctx)
270 CC_HINT(nonnull(NDEBUG_LOCATION_NONNULL(1)));
271#define fr_event_pid_reap(...) _fr_event_pid_reap(NDEBUG_LOCATION_EXP __VA_ARGS__)
272
273unsigned int fr_event_list_reap_signal(fr_event_list_t *el, fr_time_delta_t timeout, int signal);
274
276
278 TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_user_t **ev_p,
279 bool trigger, fr_event_user_cb_t callback, void *uctx);
280#define fr_event_user_insert(_ctx, _ev_p, _el, _trigger, _callback, _uctx) \
281 _fr_event_user_insert(NDEBUG_LOCATION_EXP _ctx, _ev_p, _el, _trigger, _callback, _uctx)
282
284
286
287int fr_event_pre_insert(fr_event_list_t *el, fr_event_status_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
288int fr_event_pre_delete(fr_event_list_t *el, fr_event_status_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
289
290int fr_event_post_insert(fr_event_list_t *el, fr_event_timer_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
291int fr_event_post_delete(fr_event_list_t *el, fr_event_timer_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
292
293int fr_event_corral(fr_event_list_t *el, fr_time_t now, bool wait);
295
296void fr_event_loop_exit(fr_event_list_t *el, int code);
299
300fr_event_list_t *fr_event_list_alloc(TALLOC_CTX *ctx, fr_event_status_cb_t status, void *status_ctx);
302
304
305#ifdef WITH_EVENT_DEBUG
306void fr_event_report(fr_event_list_t *el, fr_time_t now, void *uctx);
307# ifndef NDEBUG
308void fr_event_timer_dump(fr_event_list_t *el);
309# endif
310#endif
311
312#ifdef __cplusplus
313}
314#endif
#define RCSIDH(h, id)
Definition build.h:484
#define NDEBUG_LOCATION_ARGS
Pass caller information to the function.
Definition build.h:263
#define NDEBUG_LOCATION_NONNULL(_num)
Definition build.h:266
int fr_event_pre_delete(fr_event_list_t *el, fr_event_status_cb_t callback, void *uctx))
Delete a pre-event callback from the event list.
Definition event.c:2281
void fr_event_service(fr_event_list_t *el)
Service any outstanding timer or file descriptor events.
Definition event.c:2549
int fr_event_timer_delete(fr_event_timer_t const **ev)
Delete a timer event from the event list.
Definition event.c:1611
int fr_event_post_delete(fr_event_list_t *el, fr_event_timer_cb_t callback, void *uctx))
Delete a post-event callback from the event list.
Definition event.c:2335
fr_event_fd_cb_t write
The file was written to.
Definition event.h:182
int fr_event_pre_insert(fr_event_list_t *el, fr_event_status_cb_t callback, void *uctx))
Add a pre-event callback to the event list.
Definition event.c:2259
fr_event_io_func_t io
Read/write functions.
Definition event.h:199
void(* fr_event_timer_cb_t)(fr_event_list_t *el, fr_time_t now, void *uctx)
Called when a timer event fires.
Definition event.h:118
fr_time_t fr_event_list_time(fr_event_list_t *el)
Get the current server time according to the event list.
Definition event.c:643
fr_time_t fr_event_timer_when(fr_event_timer_t const *ev)
Internal timestamp representing when the timer should fire.
Definition event.c:1633
void fr_event_list_set_time_func(fr_event_list_t *el, fr_event_time_source_t func)
Override event list time source.
Definition event.c:2971
fr_event_fd_cb_t attrib
File attributes changed.
Definition event.h:184
fr_event_fd_cb_t link
The link count on the file changed.
Definition event.h:185
void(* fr_event_fd_cb_t)(fr_event_list_t *el, int fd, int flags, void *uctx)
Called when an IO event occurs on a file descriptor.
Definition event.h:137
fr_event_op_t
Operations to perform on filter.
Definition event.h:68
@ FR_EVENT_OP_SUSPEND
Temporarily remove the relevant filter from kevent.
Definition event.h:69
@ FR_EVENT_OP_RESUME
Reinsert the filter into kevent.
Definition event.h:70
int _fr_event_user_insert(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_user_t **ev_p, bool trigger, fr_event_user_cb_t callback, void *uctx)
Add a user callback to the event list.
Definition event.c:2187
fr_event_filter_t
The type of filter to install for an FD.
Definition event.h:61
@ FR_EVENT_FILTER_VNODE
Filter for vnode subfilters.
Definition event.h:63
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
Definition event.h:62
size_t offset
Offset of function in func struct.
Definition event.h:76
int fr_event_corral(fr_event_list_t *el, fr_time_t now, bool wait)
Gather outstanding timer and file descriptor events.
Definition event.c:2414
fr_event_fd_cb_t rename
The file was renamed.
Definition event.h:186
int _fr_event_timer_at(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_timer_t const **ev, fr_time_t when, fr_event_timer_cb_t callback, void const *uctx)
Insert a timer event into an event list.
Definition event.c:1451
uint64_t fr_event_list_num_timers(fr_event_list_t *el)
Return the number of timer events currently scheduled.
Definition event.c:613
int fr_event_user_trigger(fr_event_list_t *el, fr_event_user_t *ev)
Trigger a user event.
Definition event.c:2233
int fr_event_fd_unarmour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uintptr_t armour)
Unarmour an FD.
Definition event.c:1372
int _fr_event_pid_reap(NDEBUG_LOCATION_ARGS fr_event_list_t *el, pid_t pid, fr_event_pid_cb_t wait_fn, void *uctx)))
Asynchronously wait for a PID to exit, then reap it.
Definition event.c:1968
uint64_t fr_event_list_num_fds(fr_event_list_t *el)
Return the number of file descriptors is_registered with this event loop.
Definition event.c:601
fr_event_fd_cb_t read
Callback for when data is available.
Definition event.h:174
void(* fr_event_pid_cb_t)(fr_event_list_t *el, pid_t pid, int status, void *uctx)
Called when a child process has exited.
Definition event.h:156
void * fr_event_fd_uctx(fr_event_fd_t *ef)
Returns the uctx associated with an fr_event_fd_t handle.
Definition event.c:1326
void(* fr_event_error_cb_t)(fr_event_list_t *el, int fd, int flags, int fd_errno, void *uctx)
Called when an IO error event occurs on a file descriptor.
Definition event.h:147
int fr_event_list_kq(fr_event_list_t *el)
Return the kq associated with an event list.
Definition event.c:625
fr_event_fd_cb_t write
Callback for when we can write data.
Definition event.h:175
fr_event_vnode_func_t vnode
vnode callback functions.
Definition event.h:200
int fr_event_fd_armour(fr_event_list_t *el, int fd, fr_event_filter_t, uintptr_t armour)
Armour an FD.
Definition event.c:1342
bool fr_event_list_empty(fr_event_list_t *el)
Return whether the event loop has any active events.
Definition event.c:2979
unsigned int fr_event_list_reap_signal(fr_event_list_t *el, fr_time_delta_t timeout, int signal)
Send a signal to all the processes we have in our reap list, and reap them.
Definition event.c:2004
int _fr_event_timer_in(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_timer_t const **ev, fr_time_delta_t delta, fr_event_timer_cb_t callback, void const *uctx)
Insert a timer event into an event list.
Definition event.c:1596
bool fr_event_loop_exiting(fr_event_list_t *el)
Check to see whether the event loop is in the process of exiting.
Definition event.c:2755
int _fr_event_filter_update(NDEBUG_LOCATION_ARGS fr_event_list_t *el, int fd, fr_event_filter_t filter, fr_event_update_t const updates[])
Suspend/resume a subset of filters.
Definition event.c:1000
fr_time_t(* fr_event_time_source_t)(void)
Alternative time source, useful for testing.
Definition event.h:169
int _fr_event_fd_move(NDEBUG_LOCATION_ARGS fr_event_list_t *dst, fr_event_list_t *src, int fd, fr_event_filter_t filter)
Move a file descriptor event from one event list to another.
Definition event.c:949
int _fr_event_fd_insert(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, fr_event_fd_t **ef_out, fr_event_list_t *el, int fd, fr_event_fd_cb_t read_fn, fr_event_fd_cb_t write_fn, fr_event_error_cb_t error, void *uctx)
Associate I/O callbacks with a file descriptor.
Definition event.c:1233
fr_event_list_t * fr_event_list_alloc(TALLOC_CTX *ctx, fr_event_status_cb_t status, void *status_ctx)
Initialise a new event list.
Definition event.c:2899
int fr_event_timer_run(fr_event_list_t *el, fr_time_t *when)
Run a single scheduled timer event.
Definition event.c:2363
int(* fr_event_status_cb_t)(fr_time_t now, fr_time_delta_t wake, void *uctx)
Called after each event loop cycle.
Definition event.h:128
fr_event_op_t op
Operation to perform on function/filter.
Definition event.h:77
int fr_event_user_delete(fr_event_list_t *el, fr_event_user_cb_t user, void *uctx))
void fr_event_loop_exit(fr_event_list_t *el, int code)
Signal an event loop exit with the specified code.
Definition event.c:2744
int _fr_event_pid_wait(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_pid_t const **ev_p, pid_t pid, fr_event_pid_cb_t wait_fn, void *uctx)))
Insert a PID event into an event list.
Definition event.c:1741
void(* fr_event_user_cb_t)(fr_event_list_t *el, void *uctx)
Called when a user kevent occurs.
Definition event.h:163
fr_event_fd_cb_t extend
Additional files were added to a directory.
Definition event.h:183
int fr_event_fd_delete(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Remove a file descriptor from the event loop.
Definition event.c:1260
int fr_event_loop(fr_event_list_t *el)
Run an event loop.
Definition event.c:2766
fr_event_fd_t * fr_event_fd_handle(fr_event_list_t *el, int fd, fr_event_filter_t filter)
Get the opaque event handle from a file descriptor.
Definition event.c:1296
fr_event_fd_cb_t fr_event_fd_cb(fr_event_fd_t *ef, int filter, int fflags)
Returns the appropriate callback function for a given event.
Definition event.c:1318
int _fr_event_filter_insert(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, fr_event_fd_t **ef_out, fr_event_list_t *el, int fd, fr_event_filter_t filter, void *funcs, fr_event_error_cb_t error, void *uctx)
Insert a filter for the specified fd.
Definition event.c:1077
int fr_event_post_insert(fr_event_list_t *el, fr_event_timer_cb_t callback, void *uctx))
Add a post-event callback to the event list.
Definition event.c:2313
Callbacks for the FR_EVENT_FILTER_IO filter.
Definition event.h:173
Structure describing a modification to a filter's state.
Definition event.h:75
Callbacks for the FR_EVENT_FILTER_VNODE filter.
Definition event.h:180
Union of all filter functions.
Definition event.h:198
A file descriptor/filter event.
Definition event.c:294
Stores all information relating to an event list.
Definition event.c:411
A timer event.
Definition event.c:102
Callbacks for kevent() user events.
Definition event.c:375
struct fr_time_s fr_time_t
"server local" time.
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
"server local" time.
Definition time.h:69
static fr_event_list_t * el
int nonnull(2, 5))