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: b9919d54ec2dd92f6ee5c9478193d131b554e198 $")
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#include <freeradius-devel/util/timer.h>
32
33/*
34 * Allow public and private versions of the same structures
35 */
36#ifndef _EVENT_LIST_PRIVATE
38#endif
39
40/** Public event list structure
41 *
42 * Make the event timer list available, but nothing else.
43 *
44 * This allows us to access these values without the cost of a function call.
45 */
47 fr_timer_list_t *tl; //!< The timer list associated with this event loop.
48};
49
50#include <freeradius-devel/build.h>
51#include <freeradius-devel/missing.h>
52#include <freeradius-devel/util/time.h>
53
54#include <freeradius-devel/util/talloc.h>
55
56#include <stdbool.h>
57#include <sys/event.h>
58
59
60#ifdef WITH_EVENT_DEBUG
61# define EVENT_DEBUG(fmt, ...) printf("EVENT:");printf(fmt, ## __VA_ARGS__);printf("\n");
62# ifndef EVENT_REPORT_FREQ
63# define EVENT_REPORT_FREQ 5
64# endif
65#else
66# define EVENT_DEBUG(...)
67#endif
68
69/** An opaque file descriptor handle
70 */
72
73/** An opaque PID status handle
74 */
76
77/** An opaque user event handle
78 */
80
81/** The type of filter to install for an FD
82 */
83typedef enum {
84 FR_EVENT_FILTER_IO = 1, //!< Combined filter for read/write functions/
85 FR_EVENT_FILTER_VNODE //!< Filter for vnode subfilters
87
88/** Operations to perform on filter
89 */
90typedef enum {
91 FR_EVENT_OP_SUSPEND = 1, //!< Temporarily remove the relevant filter from kevent.
92 FR_EVENT_OP_RESUME //!< Reinsert the filter into kevent.
94
95/** Structure describing a modification to a filter's state
96 */
97typedef struct {
98 size_t offset; //!< Offset of function in func struct.
99 fr_event_op_t op; //!< Operation to perform on function/filter.
101
102/** Temporarily remove the filter for a func from kevent
103 *
104 * Use to populate elements in an array of #fr_event_update_t.
105 *
106 @code {.c}
107 static fr_event_update_t pause_read[] = {
108 FR_EVENT_SUSPEND(fr_event_io_func_t, read),
109 { 0 }
110 }
111 @endcode
112 *
113 * @param[in] _s the structure containing the func to suspend.
114 * @param[in] _f the func to suspend.
115 */
116#define FR_EVENT_SUSPEND(_s, _f) { .offset = offsetof(_s, _f), .op = FR_EVENT_OP_SUSPEND }
117
118/** Re-add the filter for a func from kevent
119 *
120 * Use to populate elements in an array of #fr_event_update_t.
121 *
122 @code {.c}
123 static fr_event_update_t resume_read[] = {
124 FR_EVENT_RESUME(fr_event_io_func_t, read),
125 { 0 }
126 }
127 @endcode
128 *
129 * @param[in] _s the structure containing the func to suspend.
130 * @param[in] _f the func to resume.
131 */
132#define FR_EVENT_RESUME(_s, _f) { .offset = offsetof(_s, _f), .op = FR_EVENT_OP_RESUME }
133
134/** Called after each event loop cycle
135 *
136 * Called before calling kqueue to put the thread in a sleeping state.
137 *
138 * @param[in] now The current time.
139 * @param[in] wake When we'll next need to wake up to service an event.
140 * @param[in] uctx User ctx passed to #fr_event_list_alloc.
141 */
142typedef int (*fr_event_status_cb_t)(fr_time_t now, fr_time_delta_t wake, void *uctx);
143
144/** Called when an IO event occurs on a file descriptor
145 *
146 * @param[in] el Event list the file descriptor was inserted into.
147 * @param[in] fd That experienced the IO event.
148 * @param[in] flags field as returned by kevent.
149 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
150 */
151typedef void (*fr_event_fd_cb_t)(fr_event_list_t *el, int fd, int flags, void *uctx);
152
153/** Called when an IO error event occurs on a file descriptor
154 *
155 * @param[in] el Event list the file descriptor was inserted into.
156 * @param[in] fd That experienced the IO event.
157 * @param[in] flags field as returned by kevent.
158 * @param[in] fd_errno File descriptor error.
159 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
160 */
161typedef void (*fr_event_error_cb_t)(fr_event_list_t *el, int fd, int flags, int fd_errno, void *uctx);
162
163/** Called when a child process has exited
164 *
165 * @param[in] el Event list
166 * @param[in] pid That exited
167 * @param[in] status exit status
168 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
169 */
170typedef void (*fr_event_pid_cb_t)(fr_event_list_t *el, pid_t pid, int status, void *uctx);
171
172/** Called when a user kevent occurs
173 *
174 * @param[in] el Event list
175 * @param[in] uctx User ctx passed to #fr_event_user_insert.
176 */
177typedef void (*fr_event_user_cb_t)(fr_event_list_t *el, void *uctx);
178
179/** Called when a post event fires
180 *
181 * @param[in] el Event list the post event was inserted into.
182 * @param[in] now The current time.
183 * @param[in] uctx User ctx passed to #fr_timer_in or #fr_timer_at.
184 */
185typedef void (*fr_event_post_cb_t)(fr_event_list_t *el, fr_time_t now, void *uctx);
186
187/** Callbacks for the #FR_EVENT_FILTER_IO filter
188 */
189typedef struct {
190 fr_event_fd_cb_t read; //!< Callback for when data is available.
191 fr_event_fd_cb_t write; //!< Callback for when we can write data.
193
194/** Callbacks for the #FR_EVENT_FILTER_VNODE filter
195 */
196typedef struct {
197 fr_event_fd_cb_t delete; //!< The file was deleted.
198 fr_event_fd_cb_t write; //!< The file was written to.
199 fr_event_fd_cb_t extend; //!< Additional files were added to a directory.
200 fr_event_fd_cb_t attrib; //!< File attributes changed.
201 fr_event_fd_cb_t link; //!< The link count on the file changed.
202 fr_event_fd_cb_t rename; //!< The file was renamed.
203#ifdef NOTE_REVOKE
204 fr_event_fd_cb_t revoke; //!< Volume containing the file was unmounted or
205 ///< access was revoked with revoke().
206#endif
207#ifdef NOTE_FUNLOCK
208 fr_event_fd_cb_t funlock; //!< The file was unlocked.
209#endif
211
212/** Union of all filter functions
213 */
214typedef union {
215 fr_event_io_func_t io; //!< Read/write functions.
216 fr_event_vnode_func_t vnode; //!< vnode callback functions.
218
223
225 fr_event_list_t *dst, fr_event_list_t *src, int fd, fr_event_filter_t filter);
226#define fr_event_fd_mode(...) _fr_event_fd_move(NDEBUG_LOCATION_EXP __VA_ARGS__)
227
229 TALLOC_CTX *ctx, fr_event_fd_t **ef_out,
230 fr_event_list_t *el, int fd,
231 fr_event_filter_t filter,
232 void *funcs,
234 void *uctx);
235#define fr_event_filter_insert(...) _fr_event_filter_insert(NDEBUG_LOCATION_EXP __VA_ARGS__)
236
238 fr_event_list_t *el, int fd, fr_event_filter_t filter,
239 fr_event_update_t const updates[]);
240#define fr_event_filter_update(...) _fr_event_filter_update(NDEBUG_LOCATION_EXP __VA_ARGS__)
241
243 TALLOC_CTX *ctx, fr_event_fd_t **ef_out, fr_event_list_t *el, int fd,
244 fr_event_fd_cb_t read_fn,
245 fr_event_fd_cb_t write_fn,
247 void *uctx);
248#define fr_event_fd_insert(...) _fr_event_fd_insert(NDEBUG_LOCATION_EXP __VA_ARGS__)
249
251
253
254fr_event_fd_cb_t fr_event_fd_cb(fr_event_fd_t *ef, int filter, int fflags);
255
257
258#ifndef NDEBUG
259int fr_event_fd_armour(fr_event_list_t *el, int fd, fr_event_filter_t, uintptr_t armour);
260int fr_event_fd_unarmour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uintptr_t armour);
261#endif
262
264 TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_pid_t const **ev_p,
265 pid_t pid, fr_event_pid_cb_t wait_fn, void *uctx)
266 CC_HINT(nonnull(NDEBUG_LOCATION_NONNULL(2)));
267#define fr_event_pid_wait(...) _fr_event_pid_wait(NDEBUG_LOCATION_EXP __VA_ARGS__)
268
270 fr_event_list_t *el, pid_t pid,
271 fr_event_pid_cb_t wait_fn, void *uctx)
272 CC_HINT(nonnull(NDEBUG_LOCATION_NONNULL(1)));
273#define fr_event_pid_reap(...) _fr_event_pid_reap(NDEBUG_LOCATION_EXP __VA_ARGS__)
274
275unsigned int fr_event_list_reap_signal(fr_event_list_t *el, fr_time_delta_t timeout, int signal);
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_post_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
291int fr_event_post_delete(fr_event_list_t *el, fr_event_post_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);
301
303
304#ifdef __cplusplus
305}
306#endif
#define RCSIDH(h, id)
Definition build.h:486
#define NDEBUG_LOCATION_ARGS
Pass caller information to the function.
Definition build.h:263
#define NDEBUG_LOCATION_NONNULL(_num)
Definition build.h:267
int fr_event_post_insert(fr_event_list_t *el, fr_event_post_cb_t callback, void *uctx))
Add a post-event callback to the event list.
Definition event.c:2011
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:1979
void fr_event_service(fr_event_list_t *el)
Service any outstanding timer or file descriptor events.
Definition event.c:2197
int fr_event_post_delete(fr_event_list_t *el, fr_event_post_cb_t callback, void *uctx))
Delete a post-event callback from the event list.
Definition event.c:2033
fr_event_fd_cb_t write
The file was written to.
Definition event.h:198
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:1957
fr_event_io_func_t io
Read/write functions.
Definition event.h:215
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:593
fr_event_fd_cb_t attrib
File attributes changed.
Definition event.h:200
fr_event_fd_cb_t link
The link count on the file changed.
Definition event.h:201
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:151
fr_event_op_t
Operations to perform on filter.
Definition event.h:90
@ FR_EVENT_OP_SUSPEND
Temporarily remove the relevant filter from kevent.
Definition event.h:91
@ FR_EVENT_OP_RESUME
Reinsert the filter into kevent.
Definition event.h:92
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:1885
fr_event_filter_t
The type of filter to install for an FD.
Definition event.h:83
@ FR_EVENT_FILTER_VNODE
Filter for vnode subfilters.
Definition event.h:85
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
Definition event.h:84
size_t offset
Offset of function in func struct.
Definition event.h:98
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:2062
fr_event_fd_cb_t rename
The file was renamed.
Definition event.h:202
uint64_t fr_event_list_num_timers(fr_event_list_t *el)
Return the number of timer events currently scheduled.
Definition event.c:563
fr_timer_list_t * tl
The timer list associated with this event loop.
Definition event.h:47
int fr_event_user_trigger(fr_event_list_t *el, fr_event_user_t *ev)
Trigger a user event.
Definition event.c:1931
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:1318
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:1666
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:551
fr_event_fd_cb_t read
Callback for when data is available.
Definition event.h:190
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:170
void * fr_event_fd_uctx(fr_event_fd_t *ef)
Returns the uctx associated with an fr_event_fd_t handle.
Definition event.c:1272
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:161
int fr_event_list_kq(fr_event_list_t *el)
Return the kq associated with an event list.
Definition event.c:575
fr_event_fd_cb_t write
Callback for when we can write data.
Definition event.h:191
fr_event_vnode_func_t vnode
vnode callback functions.
Definition event.h:216
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:1288
bool fr_event_list_empty(fr_event_list_t *el)
Return whether the event loop has any active events.
Definition event.c:2590
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:1702
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:2386
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:946
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:895
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:1179
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:2526
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:142
void(* fr_event_post_cb_t)(fr_event_list_t *el, fr_time_t now, void *uctx)
Called when a post event fires.
Definition event.h:185
fr_event_op_t op
Operation to perform on function/filter.
Definition event.h:99
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:2375
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:1439
void(* fr_event_user_cb_t)(fr_event_list_t *el, void *uctx)
Called when a user kevent occurs.
Definition event.h:177
fr_event_fd_cb_t extend
Additional files were added to a directory.
Definition event.h:199
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:1206
int fr_event_loop(fr_event_list_t *el)
Run an event loop.
Definition event.c:2397
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:1242
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:1264
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:1023
Callbacks for the FR_EVENT_FILTER_IO filter.
Definition event.h:189
Public event list structure.
Definition event.h:46
Structure describing a modification to a filter's state.
Definition event.h:97
Callbacks for the FR_EVENT_FILTER_VNODE filter.
Definition event.h:196
Union of all filter functions.
Definition event.h:214
A file descriptor/filter event.
Definition event.c:263
Stores all information relating to an event list.
Definition event.c:380
Callbacks for kevent() user events.
Definition event.c:344
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
"server local" time.
Definition time.h:69
An event timer list.
Definition timer.c:53
static fr_event_list_t * el
int nonnull(2, 5))