Coverage Report

Created: 2026-05-11 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/freeradius-devel/util/timer.h
Line
Count
Source
1
#pragma once
2
3
/*
4
 *  This program is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program; if not, write to the Free Software
16
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17
 */
18
19
/** Timer lists with event callbacks
20
 *
21
 * @file src/lib/util/event.h
22
 *
23
 * @copyright 2025 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24
 */
25
RCSIDH(timer_h, "$Id: b57afbaa66f82bb1d24303a7804e42862b132aed $")
26
27
#ifdef __cplusplus
28
extern "C" {
29
#endif
30
31
#include <freeradius-devel/util/time.h>
32
#include <freeradius-devel/util/misc.h>
33
#include <freeradius-devel/util/talloc.h>
34
35
/*
36
 *  Allow public and private versions of the same structures
37
 */
38
#ifdef _CONST
39
#  error _CONST can only be defined in the local header
40
#endif
41
#ifndef _TIMER_PRIVATE
42
typedef struct fr_timer_list_pub_s fr_timer_list_t;
43
#  define _CONST const
44
#else
45
#  define _CONST
46
#endif
47
48
/** Alternative time source, useful for testing
49
 *
50
 * @return the current time in nanoseconds past the epoch.
51
 */
52
typedef fr_time_t (*fr_event_time_source_t)(void);
53
54
/** Public event timer list structure
55
 *
56
 * Make the current list time, and time source available, but nothing else.
57
 *
58
 * This allows us to access these values without the cost of a function call.
59
 */
60
struct fr_timer_list_pub_s {
61
  fr_event_time_source_t _CONST time; //!< Time source this list uses to get the current time
62
            ///< when calculating deltas (fr_timer_in).
63
};
64
65
/** An opaque timer handle
66
 */
67
typedef struct fr_timer_s fr_timer_t;
68
69
/** Called when a timer event fires
70
 *
71
 * @param[in] tl  timer list event was inserted into.
72
 * @param[in] now The current time.
73
 * @param[in] uctx  User ctx passed to #fr_timer_in or #fr_timer_at.
74
 */
75
typedef void (*fr_timer_cb_t)(fr_timer_list_t *tl, fr_time_t now, void *uctx);
76
77
int     _fr_timer_at(NDEBUG_LOCATION_ARGS
78
             TALLOC_CTX *ctx, fr_timer_list_t *tl, fr_timer_t **ev,
79
             fr_time_t when, bool free_on_fire, fr_timer_cb_t callback, void const *uctx)
80
             CC_HINT(nonnull(NDEBUG_LOCATION_NONNULL(2), NDEBUG_LOCATION_NONNULL(3), NDEBUG_LOCATION_NONNULL(6)));
81
0
#define     fr_timer_at(...) _fr_timer_at(NDEBUG_LOCATION_EXP __VA_ARGS__)
82
83
int     _fr_timer_in(NDEBUG_LOCATION_ARGS
84
             TALLOC_CTX *ctx, fr_timer_list_t *tl, fr_timer_t **ev,
85
             fr_time_delta_t delta, bool free_on_fire, fr_timer_cb_t callback, void const *uctx)
86
             CC_HINT(nonnull(NDEBUG_LOCATION_NONNULL(2), NDEBUG_LOCATION_NONNULL(3), NDEBUG_LOCATION_NONNULL(6)));
87
0
#define     fr_timer_in(...) _fr_timer_in(NDEBUG_LOCATION_EXP __VA_ARGS__)
88
89
int     fr_timer_disarm(fr_timer_t *ev);      /* disarms but does not free */
90
91
#define     FR_TIMER_DISARM(_ev) \
92
0
      do { \
93
0
        if (likely((_ev) != NULL) && unlikely(fr_timer_disarm(_ev) < 0)) { \
94
0
          fr_assert_msg(0, "Failed to disarm timer %p", (_ev)); \
95
0
        } \
96
0
      } while (0)
97
98
#define     FR_TIMER_DISARM_RETURN(_ev) \
99
0
        if ((likely(((_ev)) != NULL) && unlikely(!fr_cond_assert_msg(fr_timer_disarm(_ev) == 0, "Failed to disarm timer %p", (_ev))))) return -1;
100
101
int     fr_timer_delete(fr_timer_t **ev_p) CC_HINT(nonnull);  /* disarms AND frees */
102
103
#define     FR_TIMER_DELETE(_ev_p) \
104
0
      do { \
105
0
        if ((likely((*(_ev_p)) != NULL) && unlikely(fr_timer_delete(_ev_p) < 0))) { \
106
0
          fr_assert_msg(0, "Failed to delete timer %p", *(_ev_p)); \
107
0
        } \
108
0
      } while (0)
109
110
#define     FR_TIMER_DELETE_RETURN(_ev_p) \
111
0
        if ((likely((*(_ev_p)) != NULL) && unlikely(!fr_cond_assert_msg(fr_timer_delete(_ev_p) == 0, "Failed to delete timer %p", *(_ev_p))))) return -1;
112
113
fr_time_t   fr_timer_when(fr_timer_t *ev) CC_HINT(nonnull);
114
115
fr_time_delta_t   fr_timer_remaining(fr_timer_t *ev) CC_HINT(nonnull);
116
117
bool      _fr_timer_armed(fr_timer_t *ev);
118
119
/* Wrapper to avoid overhead of function call on NULL */
120
0
static inline bool  fr_timer_armed(fr_timer_t *ev) { return ev && _fr_timer_armed(ev); }
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_timer_armed
Unexecuted instantiation: fuzzer_util.c:fr_timer_armed
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_timer_armed
Unexecuted instantiation: fuzzer_cbor.c:fr_timer_armed
Unexecuted instantiation: fuzzer_der.c:fr_timer_armed
Unexecuted instantiation: fuzzer_dns.c:fr_timer_armed
Unexecuted instantiation: fuzzer_tacacs.c:fr_timer_armed
Unexecuted instantiation: fuzzer_bfd.c:fr_timer_armed
Unexecuted instantiation: fuzzer_radius.c:fr_timer_armed
Unexecuted instantiation: fuzzer_tftp.c:fr_timer_armed
Unexecuted instantiation: fuzzer_vmps.c:fr_timer_armed
Unexecuted instantiation: base32.c:fr_timer_armed
Unexecuted instantiation: base64.c:fr_timer_armed
Unexecuted instantiation: calc.c:fr_timer_armed
Unexecuted instantiation: cbor.c:fr_timer_armed
Unexecuted instantiation: decode.c:fr_timer_armed
Unexecuted instantiation: dict_ext.c:fr_timer_armed
Unexecuted instantiation: dict_fixup.c:fr_timer_armed
Unexecuted instantiation: dict_print.c:fr_timer_armed
Unexecuted instantiation: dict_test.c:fr_timer_armed
Unexecuted instantiation: dict_tokenize.c:fr_timer_armed
Unexecuted instantiation: dict_unknown.c:fr_timer_armed
Unexecuted instantiation: dict_util.c:fr_timer_armed
Unexecuted instantiation: dict_validate.c:fr_timer_armed
Unexecuted instantiation: dl.c:fr_timer_armed
Unexecuted instantiation: dns.c:fr_timer_armed
Unexecuted instantiation: edit.c:fr_timer_armed
Unexecuted instantiation: encode.c:fr_timer_armed
Unexecuted instantiation: event.c:fr_timer_armed
Unexecuted instantiation: timer.c:fr_timer_armed
Unexecuted instantiation: file.c:fr_timer_armed
Unexecuted instantiation: inet.c:fr_timer_armed
Unexecuted instantiation: log.c:fr_timer_armed
Unexecuted instantiation: packet.c:fr_timer_armed
Unexecuted instantiation: pair.c:fr_timer_armed
Unexecuted instantiation: pair_inline.c:fr_timer_armed
Unexecuted instantiation: pair_legacy.c:fr_timer_armed
Unexecuted instantiation: pair_print.c:fr_timer_armed
Unexecuted instantiation: pair_tokenize.c:fr_timer_armed
Unexecuted instantiation: print.c:fr_timer_armed
Unexecuted instantiation: proto.c:fr_timer_armed
Unexecuted instantiation: regex.c:fr_timer_armed
Unexecuted instantiation: socket.c:fr_timer_armed
Unexecuted instantiation: stats.c:fr_timer_armed
Unexecuted instantiation: struct.c:fr_timer_armed
Unexecuted instantiation: syserror.c:fr_timer_armed
Unexecuted instantiation: types.c:fr_timer_armed
Unexecuted instantiation: udp.c:fr_timer_armed
Unexecuted instantiation: udp_queue.c:fr_timer_armed
Unexecuted instantiation: uri.c:fr_timer_armed
Unexecuted instantiation: value.c:fr_timer_armed
Unexecuted instantiation: fuzzer.c:fr_timer_armed
Unexecuted instantiation: base.c:fr_timer_armed
Unexecuted instantiation: raw.c:fr_timer_armed
Unexecuted instantiation: json.c:fr_timer_armed
Unexecuted instantiation: jpath.c:fr_timer_armed
Unexecuted instantiation: cache.c:fr_timer_armed
Unexecuted instantiation: cert.c:fr_timer_armed
Unexecuted instantiation: conf.c:fr_timer_armed
Unexecuted instantiation: ctx.c:fr_timer_armed
Unexecuted instantiation: engine.c:fr_timer_armed
Unexecuted instantiation: pairs.c:fr_timer_armed
Unexecuted instantiation: session.c:fr_timer_armed
Unexecuted instantiation: strerror.c:fr_timer_armed
Unexecuted instantiation: utils.c:fr_timer_armed
Unexecuted instantiation: verify.c:fr_timer_armed
Unexecuted instantiation: version.c:fr_timer_armed
Unexecuted instantiation: virtual_server.c:fr_timer_armed
Unexecuted instantiation: list.c:fr_timer_armed
Unexecuted instantiation: tcp.c:fr_timer_armed
Unexecuted instantiation: abinary.c:fr_timer_armed
Unexecuted instantiation: auth.c:fr_timer_armed
Unexecuted instantiation: cf_file.c:fr_timer_armed
Unexecuted instantiation: cf_parse.c:fr_timer_armed
Unexecuted instantiation: cf_util.c:fr_timer_armed
Unexecuted instantiation: client.c:fr_timer_armed
Unexecuted instantiation: command.c:fr_timer_armed
Unexecuted instantiation: connection.c:fr_timer_armed
Unexecuted instantiation: dependency.c:fr_timer_armed
Unexecuted instantiation: dl_module.c:fr_timer_armed
Unexecuted instantiation: exec.c:fr_timer_armed
Unexecuted instantiation: exec_legacy.c:fr_timer_armed
Unexecuted instantiation: exfile.c:fr_timer_armed
Unexecuted instantiation: global_lib.c:fr_timer_armed
Unexecuted instantiation: main_config.c:fr_timer_armed
Unexecuted instantiation: main_loop.c:fr_timer_armed
Unexecuted instantiation: map.c:fr_timer_armed
Unexecuted instantiation: map_proc.c:fr_timer_armed
Unexecuted instantiation: module.c:fr_timer_armed
Unexecuted instantiation: module_method.c:fr_timer_armed
Unexecuted instantiation: module_rlm.c:fr_timer_armed
Unexecuted instantiation: paircmp.c:fr_timer_armed
Unexecuted instantiation: pairmove.c:fr_timer_armed
Unexecuted instantiation: password.c:fr_timer_armed
Unexecuted instantiation: pool.c:fr_timer_armed
Unexecuted instantiation: request.c:fr_timer_armed
Unexecuted instantiation: request_data.c:fr_timer_armed
Unexecuted instantiation: section.c:fr_timer_armed
Unexecuted instantiation: snmp.c:fr_timer_armed
Unexecuted instantiation: state.c:fr_timer_armed
Unexecuted instantiation: tmpl_dcursor.c:fr_timer_armed
Unexecuted instantiation: tmpl_eval.c:fr_timer_armed
Unexecuted instantiation: tmpl_tokenize.c:fr_timer_armed
Unexecuted instantiation: trigger.c:fr_timer_armed
Unexecuted instantiation: trunk.c:fr_timer_armed
Unexecuted instantiation: users_file.c:fr_timer_armed
Unexecuted instantiation: util.c:fr_timer_armed
Unexecuted instantiation: virtual_servers.c:fr_timer_armed
Unexecuted instantiation: call.c:fr_timer_armed
Unexecuted instantiation: call_env.c:fr_timer_armed
Unexecuted instantiation: caller.c:fr_timer_armed
Unexecuted instantiation: catch.c:fr_timer_armed
Unexecuted instantiation: child_request.c:fr_timer_armed
Unexecuted instantiation: compile.c:fr_timer_armed
Unexecuted instantiation: condition.c:fr_timer_armed
Unexecuted instantiation: detach.c:fr_timer_armed
Unexecuted instantiation: finally.c:fr_timer_armed
Unexecuted instantiation: foreach.c:fr_timer_armed
Unexecuted instantiation: function.c:fr_timer_armed
Unexecuted instantiation: group.c:fr_timer_armed
Unexecuted instantiation: interpret.c:fr_timer_armed
Unexecuted instantiation: interpret_synchronous.c:fr_timer_armed
Unexecuted instantiation: io.c:fr_timer_armed
Unexecuted instantiation: limit.c:fr_timer_armed
Unexecuted instantiation: load_balance.c:fr_timer_armed
Unexecuted instantiation: map_builtin.c:fr_timer_armed
Unexecuted instantiation: parallel.c:fr_timer_armed
Unexecuted instantiation: return.c:fr_timer_armed
Unexecuted instantiation: subrequest.c:fr_timer_armed
Unexecuted instantiation: switch.c:fr_timer_armed
Unexecuted instantiation: timeout.c:fr_timer_armed
Unexecuted instantiation: tmpl.c:fr_timer_armed
Unexecuted instantiation: try.c:fr_timer_armed
Unexecuted instantiation: transaction.c:fr_timer_armed
Unexecuted instantiation: xlat.c:fr_timer_armed
Unexecuted instantiation: xlat_alloc.c:fr_timer_armed
Unexecuted instantiation: xlat_builtin.c:fr_timer_armed
Unexecuted instantiation: xlat_eval.c:fr_timer_armed
Unexecuted instantiation: xlat_expr.c:fr_timer_armed
Unexecuted instantiation: xlat_func.c:fr_timer_armed
Unexecuted instantiation: xlat_inst.c:fr_timer_armed
Unexecuted instantiation: xlat_pair.c:fr_timer_armed
Unexecuted instantiation: xlat_purify.c:fr_timer_armed
Unexecuted instantiation: xlat_redundant.c:fr_timer_armed
Unexecuted instantiation: xlat_tokenize.c:fr_timer_armed
Unexecuted instantiation: app_io.c:fr_timer_armed
Unexecuted instantiation: channel.c:fr_timer_armed
Unexecuted instantiation: control.c:fr_timer_armed
Unexecuted instantiation: coord.c:fr_timer_armed
Unexecuted instantiation: coord_pair.c:fr_timer_armed
Unexecuted instantiation: load.c:fr_timer_armed
Unexecuted instantiation: master.c:fr_timer_armed
Unexecuted instantiation: network.c:fr_timer_armed
Unexecuted instantiation: schedule.c:fr_timer_armed
Unexecuted instantiation: thread.c:fr_timer_armed
Unexecuted instantiation: worker.c:fr_timer_armed
Unexecuted instantiation: vmps.c:fr_timer_armed
121
122
int     fr_timer_uctx_insert(fr_timer_list_t *tl, void *uctx) CC_HINT(nonnull);
123
124
int     fr_timer_uctx_remove(fr_timer_list_t *tl, void *uctx) CC_HINT(nonnull);
125
126
void      *fr_timer_uctx_peek(fr_timer_list_t *tl) CC_HINT(nonnull);
127
128
129
int     fr_timer_list_force_run(fr_timer_list_t *tl) CC_HINT(nonnull);
130
131
int     fr_timer_list_run(fr_timer_list_t *tl, fr_time_t *when);
132
133
int     fr_timer_list_disarm(fr_timer_list_t *tl) CC_HINT(nonnull);
134
135
int     fr_timer_list_arm(fr_timer_list_t *tl) CC_HINT(nonnull);
136
137
uint64_t    fr_timer_list_num_events(fr_timer_list_t *tl) CC_HINT(nonnull);
138
139
fr_time_t   fr_timer_list_when(fr_timer_list_t *tl) CC_HINT(nonnull);
140
141
void      fr_timer_list_set_time_func(fr_timer_list_t *tl, fr_event_time_source_t func) CC_HINT(nonnull);
142
143
fr_timer_list_t   *fr_timer_list_lst_alloc(TALLOC_CTX *ctx, fr_timer_list_t *parent);
144
145
fr_timer_list_t   *fr_timer_list_ordered_alloc(TALLOC_CTX *ctx, fr_timer_list_t *parent);
146
147
fr_timer_list_t   *fr_timer_list_shared_alloc(TALLOC_CTX *ctx, fr_timer_list_t *parent, fr_cmp_t cmp,
148
                fr_timer_cb_t callback, size_t node_offset, size_t time_offset) CC_HINT(nonnull);
149
150
#ifdef WITH_EVENT_DEBUG
151
void      fr_timer_report(fr_timer_list_t *tl, fr_time_t now, void *uctx);
152
void      fr_timer_dump(fr_timer_list_t *tl);
153
#endif
154
155
#undef _CONST
156
157
#ifdef __cplusplus
158
}
159
#endif