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: 9f516e4fc8209c84b571e72de32accebf0c62ed2 $")
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 <sys/event.h>
57
58
59#ifdef WITH_EVENT_DEBUG
60# define EVENT_DEBUG(fmt, ...) printf("EVENT:");printf(fmt, ## __VA_ARGS__);printf("\n");
61# ifndef EVENT_REPORT_FREQ
62# define EVENT_REPORT_FREQ 5
63# endif
64#else
65# define EVENT_DEBUG(...)
66#endif
67
68/** An opaque file descriptor handle
69 */
71
72/** An opaque PID status handle
73 */
75
76/** An opaque user event handle
77 */
79
80/** The type of filter to install for an FD
81 */
82typedef enum {
83 FR_EVENT_FILTER_IO = 1, //!< Combined filter for read/write functions/
84 FR_EVENT_FILTER_VNODE //!< Filter for vnode subfilters
86
87/** Operations to perform on filter
88 */
89typedef enum {
90 FR_EVENT_OP_SUSPEND = 1, //!< Temporarily remove the relevant filter from kevent.
91 FR_EVENT_OP_RESUME //!< Reinsert the filter into kevent.
93
94/** Structure describing a modification to a filter's state
95 */
96typedef struct {
97 size_t offset; //!< Offset of function in func struct.
98 fr_event_op_t op; //!< Operation to perform on function/filter.
100
101/** Temporarily remove the filter for a func from kevent
102 *
103 * Use to populate elements in an array of #fr_event_update_t.
104 *
105 @code {.c}
106 static fr_event_update_t pause_read[] = {
107 FR_EVENT_SUSPEND(fr_event_io_func_t, read),
108 { 0 }
109 }
110 @endcode
111 *
112 * @param[in] _s the structure containing the func to suspend.
113 * @param[in] _f the func to suspend.
114 */
115#define FR_EVENT_SUSPEND(_s, _f) { .offset = offsetof(_s, _f), .op = FR_EVENT_OP_SUSPEND }
116
117/** Re-add the filter for a func from kevent
118 *
119 * Use to populate elements in an array of #fr_event_update_t.
120 *
121 @code {.c}
122 static fr_event_update_t resume_read[] = {
123 FR_EVENT_RESUME(fr_event_io_func_t, read),
124 { 0 }
125 }
126 @endcode
127 *
128 * @param[in] _s the structure containing the func to suspend.
129 * @param[in] _f the func to resume.
130 */
131#define FR_EVENT_RESUME(_s, _f) { .offset = offsetof(_s, _f), .op = FR_EVENT_OP_RESUME }
132
133/** Called after each event loop cycle
134 *
135 * Called before calling kqueue to put the thread in a sleeping state.
136 *
137 * @param[in] now The current time.
138 * @param[in] wake When we'll next need to wake up to service an event.
139 * @param[in] uctx User ctx passed to #fr_event_list_alloc.
140 */
141typedef int (*fr_event_status_cb_t)(fr_time_t now, fr_time_delta_t wake, void *uctx);
142
143/** Called when an IO event occurs on a file descriptor
144 *
145 * @param[in] el Event list the file descriptor was inserted into.
146 * @param[in] fd That experienced the IO event.
147 * @param[in] flags field as returned by kevent.
148 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
149 */
150typedef void (*fr_event_fd_cb_t)(fr_event_list_t *el, int fd, int flags, void *uctx);
151
152/** Called when an IO error event occurs on a file descriptor
153 *
154 * @param[in] el Event list the file descriptor was inserted into.
155 * @param[in] fd That experienced the IO event.
156 * @param[in] flags field as returned by kevent.
157 * @param[in] fd_errno File descriptor error.
158 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
159 */
160typedef void (*fr_event_error_cb_t)(fr_event_list_t *el, int fd, int flags, int fd_errno, void *uctx);
161
162/** Called when a child process has exited
163 *
164 * @param[in] el Event list
165 * @param[in] pid That exited
166 * @param[in] status exit status
167 * @param[in] uctx User ctx passed to #fr_event_fd_insert.
168 */
169typedef void (*fr_event_pid_cb_t)(fr_event_list_t *el, pid_t pid, int status, void *uctx);
170
171/** Called when a user kevent occurs
172 *
173 * @param[in] el Event list
174 * @param[in] uctx User ctx passed to #fr_event_user_insert.
175 */
176typedef void (*fr_event_user_cb_t)(fr_event_list_t *el, void *uctx);
177
178/** Called when a post event fires
179 *
180 * @param[in] el Event list the post event was inserted into.
181 * @param[in] now The current time.
182 * @param[in] uctx User ctx passed to #fr_timer_in or #fr_timer_at.
183 */
184typedef void (*fr_event_post_cb_t)(fr_event_list_t *el, fr_time_t now, void *uctx);
185
186/** Callbacks for the #FR_EVENT_FILTER_IO filter
187 */
188typedef struct {
189 fr_event_fd_cb_t read; //!< Callback for when data is available.
190 fr_event_fd_cb_t write; //!< Callback for when we can write data.
192
193/** Callbacks for the #FR_EVENT_FILTER_VNODE filter
194 */
195typedef struct {
196 fr_event_fd_cb_t delete; //!< The file was deleted.
197 fr_event_fd_cb_t write; //!< The file was written to.
198 fr_event_fd_cb_t extend; //!< Additional files were added to a directory.
199 fr_event_fd_cb_t attrib; //!< File attributes changed.
200 fr_event_fd_cb_t link; //!< The link count on the file changed.
201 fr_event_fd_cb_t rename; //!< The file was renamed.
202#ifdef NOTE_REVOKE
203 fr_event_fd_cb_t revoke; //!< Volume containing the file was unmounted or
204 ///< access was revoked with revoke().
205#endif
206#ifdef NOTE_FUNLOCK
207 fr_event_fd_cb_t funlock; //!< The file was unlocked.
208#endif
210
211/** Union of all filter functions
212 */
213typedef union {
214 fr_event_io_func_t io; //!< Read/write functions.
215 fr_event_vnode_func_t vnode; //!< vnode callback functions.
217
222
224 fr_event_list_t *dst, fr_event_list_t *src, int fd, fr_event_filter_t filter);
225#define fr_event_fd_mode(...) _fr_event_fd_move(NDEBUG_LOCATION_EXP __VA_ARGS__)
226
228 TALLOC_CTX *ctx, fr_event_fd_t **ef_out,
229 fr_event_list_t *el, int fd,
230 fr_event_filter_t filter,
231 void *funcs,
233 void *uctx);
234#define fr_event_filter_insert(...) _fr_event_filter_insert(NDEBUG_LOCATION_EXP __VA_ARGS__)
235
237 fr_event_list_t *el, int fd, fr_event_filter_t filter,
238 fr_event_update_t const updates[]);
239#define fr_event_filter_update(...) _fr_event_filter_update(NDEBUG_LOCATION_EXP __VA_ARGS__)
240
242 TALLOC_CTX *ctx, fr_event_fd_t **ef_out, fr_event_list_t *el, int fd,
243 fr_event_fd_cb_t read_fn,
244 fr_event_fd_cb_t write_fn,
246 void *uctx);
247#define fr_event_fd_insert(...) _fr_event_fd_insert(NDEBUG_LOCATION_EXP __VA_ARGS__)
248
250
252
253fr_event_fd_cb_t fr_event_fd_cb(fr_event_fd_t *ef, int filter, int fflags);
254
256
257#ifndef NDEBUG
258int fr_event_fd_armour(fr_event_list_t *el, int fd, fr_event_filter_t, uintptr_t armour);
259int fr_event_fd_unarmour(fr_event_list_t *el, int fd, fr_event_filter_t filter, uintptr_t armour);
260#endif
261
263 TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_pid_t const **ev_p,
264 pid_t pid, fr_event_pid_cb_t wait_fn, void *uctx)
265 CC_HINT(nonnull(NDEBUG_LOCATION_NONNULL(2)));
266#define fr_event_pid_wait(...) _fr_event_pid_wait(NDEBUG_LOCATION_EXP __VA_ARGS__)
267
269 fr_event_list_t *el, pid_t pid,
270 fr_event_pid_cb_t wait_fn, void *uctx)
271 CC_HINT(nonnull(NDEBUG_LOCATION_NONNULL(1)));
272#define fr_event_pid_reap(...) _fr_event_pid_reap(NDEBUG_LOCATION_EXP __VA_ARGS__)
273
274unsigned int fr_event_list_reap_signal(fr_event_list_t *el, fr_time_delta_t timeout, int signal);
275
277 TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_user_t **ev_p,
278 bool trigger, fr_event_user_cb_t callback, void *uctx);
279#define fr_event_user_insert(_ctx, _el, _ev_p, _trigger, _callback, _uctx) \
280 _fr_event_user_insert(NDEBUG_LOCATION_EXP _ctx, _el, _ev_p, _trigger, _callback, _uctx)
281
283
285
286int fr_event_pre_insert(fr_event_list_t *el, fr_event_status_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
287int fr_event_pre_delete(fr_event_list_t *el, fr_event_status_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
288
289int fr_event_post_insert(fr_event_list_t *el, fr_event_post_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
290int fr_event_post_delete(fr_event_list_t *el, fr_event_post_cb_t callback, void *uctx) CC_HINT(nonnull(1,2));
291
292int fr_event_corral(fr_event_list_t *el, fr_time_t now, bool wait);
294
295void fr_event_loop_exit(fr_event_list_t *el, int code);
298
299fr_event_list_t *fr_event_list_alloc(TALLOC_CTX *ctx, fr_event_status_cb_t status, void *status_ctx);
300
302
303#ifdef __cplusplus
304}
305#endif
#define RCSIDH(h, id)
Definition build.h:507
#define NDEBUG_LOCATION_ARGS
Pass caller information to the function.
Definition build.h:282
#define NDEBUG_LOCATION_NONNULL(_num)
Definition build.h:286
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:2000
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:1975
void fr_event_service(fr_event_list_t *el)
Service any outstanding timer or file descriptor events.
Definition event.c:2177
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:2023
fr_event_fd_cb_t write
The file was written to.
Definition event.h:197
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:1953
fr_event_io_func_t io
Read/write functions.
Definition event.h:214
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:590
fr_event_fd_cb_t attrib
File attributes changed.
Definition event.h:199
fr_event_fd_cb_t link
The link count on the file changed.
Definition event.h:200
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:150
fr_event_op_t
Operations to perform on filter.
Definition event.h:89
@ FR_EVENT_OP_SUSPEND
Temporarily remove the relevant filter from kevent.
Definition event.h:90
@ FR_EVENT_OP_RESUME
Reinsert the filter into kevent.
Definition event.h:91
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:1882
fr_event_filter_t
The type of filter to install for an FD.
Definition event.h:82
@ FR_EVENT_FILTER_VNODE
Filter for vnode subfilters.
Definition event.h:84
@ FR_EVENT_FILTER_IO
Combined filter for read/write functions/.
Definition event.h:83
size_t offset
Offset of function in func struct.
Definition event.h:97
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:2045
fr_event_fd_cb_t rename
The file was renamed.
Definition event.h:201
uint64_t fr_event_list_num_timers(fr_event_list_t *el)
Return the number of timer events currently scheduled.
Definition event.c:560
fr_timer_list_t * tl
The timer list associated with this event loop.
Definition event.h:47
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:1315
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:1663
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:548
fr_event_fd_cb_t read
Callback for when data is available.
Definition event.h:189
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:169
void * fr_event_fd_uctx(fr_event_fd_t *ef)
Returns the uctx associated with an fr_event_fd_t handle.
Definition event.c:1269
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:160
int fr_event_list_kq(fr_event_list_t *el)
Return the kq associated with an event list.
Definition event.c:572
fr_event_fd_cb_t write
Callback for when we can write data.
Definition event.h:190
fr_event_vnode_func_t vnode
vnode callback functions.
Definition event.h:215
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:1285
bool fr_event_list_empty(fr_event_list_t *el)
Return whether the event loop has any active events.
Definition event.c:2570
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:1699
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:2366
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:943
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:892
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:1176
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:2506
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:141
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:184
fr_event_op_t op
Operation to perform on function/filter.
Definition event.h:98
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:2355
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:1436
void(* fr_event_user_cb_t)(fr_event_list_t *el, void *uctx)
Called when a user kevent occurs.
Definition event.h:176
fr_event_fd_cb_t extend
Additional files were added to a directory.
Definition event.h:198
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:1203
int fr_event_loop(fr_event_list_t *el)
Run an event loop.
Definition event.c:2377
int fr_event_user_trigger(fr_event_user_t *ev)
Trigger a user event.
Definition event.c:1927
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:1239
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:1261
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:1020
Callbacks for the FR_EVENT_FILTER_IO filter.
Definition event.h:188
Public event list structure.
Definition event.h:46
Structure describing a modification to a filter's state.
Definition event.h:96
Callbacks for the FR_EVENT_FILTER_VNODE filter.
Definition event.h:195
Union of all filter functions.
Definition event.h:213
A file descriptor/filter event.
Definition event.c:260
Stores all information relating to an event list.
Definition event.c:377
Callbacks for kevent() user events.
Definition event.c:341
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:49
int trigger(unlang_interpret_t *intp, CONF_SECTION const *cs, CONF_PAIR **trigger_cp, char const *name, bool rate_limit, fr_pair_list_t *args)
Execute a trigger - call an executable to process an event.
Definition trigger.c:155
static fr_event_list_t * el
int nonnull(2, 5))