]> git.ipfire.org Git - thirdparty/bird.git/blame - lib/event.c
unsigned [int] -> uint
[thirdparty/bird.git] / lib / event.c
CommitLineData
3b15402f
MM
1/*
2 * BIRD Library -- Event Processing
3 *
4 * (c) 1999 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
525fa2c1
MM
9/**
10 * DOC: Events
11 *
12 * Events are there to keep track of deferred execution.
13 * Since BIRD is single-threaded, it requires long lasting tasks to be split to smaller
14 * parts, so that no module can monopolize the CPU. To split such a task, just create
15 * an &event resource, point it to the function you want to have called and call ev_schedule()
58f7d004 16 * to ask the core to run the event when nothing more important requires attention.
525fa2c1
MM
17 *
18 * You can also define your own event lists (the &event_list structure), enqueue your
19 * events in them and explicitly ask to run them.
525fa2c1
MM
20 */
21
3b15402f
MM
22#include "nest/bird.h"
23#include "lib/event.h"
24
25event_list global_event_list;
26
27inline void
28ev_postpone(event *e)
29{
6f8bbaa1 30 if (ev_active(e))
3b15402f
MM
31 {
32 rem_node(&e->n);
33 e->n.next = NULL;
34 }
35}
36
37static void
38ev_dump(resource *r)
39{
40 event *e = (event *) r;
41
42 debug("(code %p, data %p, %s)\n",
43 e->hook,
44 e->data,
45 e->n.next ? "scheduled" : "inactive");
46}
47
48static struct resclass ev_class = {
49 "Event",
67bd949a 50 sizeof(event),
3b15402f 51 (void (*)(resource *)) ev_postpone,
e81b440f 52 ev_dump,
acb60628 53 NULL,
e81b440f 54 NULL
3b15402f
MM
55};
56
525fa2c1
MM
57/**
58 * ev_new - create a new event
59 * @p: resource pool
60 *
61 * This function creates a new event resource. To use it,
62 * you need to fill the structure fields and call ev_schedule().
63 */
3b15402f
MM
64event *
65ev_new(pool *p)
66{
67 event *e = ralloc(p, &ev_class);
3b15402f
MM
68 return e;
69}
70
525fa2c1
MM
71/**
72 * ev_run - run an event
73 * @e: an event
74 *
75 * This function explicitly runs the event @e (calls its hook
76 * function) and removes it from an event list if it's linked to any.
77 *
78 * From the hook function, you can call ev_enqueue() or ev_schedule()
79 * to re-add the event.
80 */
8f6accb5 81inline void
3b15402f
MM
82ev_run(event *e)
83{
8f6accb5
MM
84 ev_postpone(e);
85 e->hook(e->data);
3b15402f
MM
86}
87
525fa2c1
MM
88/**
89 * ev_enqueue - enqueue an event
90 * @l: an event list
91 * @e: an event
92 *
93 * ev_enqueue() stores the event @e to the specified event
94 * list @l which can be run by calling ev_run_list().
95 */
3b15402f
MM
96inline void
97ev_enqueue(event_list *l, event *e)
98{
8f6accb5 99 ev_postpone(e);
3b15402f
MM
100 add_tail(l, &e->n);
101}
102
525fa2c1
MM
103/**
104 * ev_schedule - schedule an event
105 * @e: an event
106 *
107 * This function schedules an event by enqueueing it to a system-wide
108 * event list which is run by the platform dependent code whenever
109 * appropriate.
110 */
3b15402f
MM
111void
112ev_schedule(event *e)
113{
114 ev_enqueue(&global_event_list, e);
115}
116
8bcb5fb1
OZ
117void io_log_event(void *hook, void *data);
118
525fa2c1
MM
119/**
120 * ev_run_list - run an event list
121 * @l: an event list
122 *
123 * This function calls ev_run() for all events enqueued in the list @l.
124 */
84a7d7f7 125int
3b15402f
MM
126ev_run_list(event_list *l)
127{
b933281e 128 node *n;
8f6accb5 129 list tmp_list;
0d70292d 130
8f6accb5
MM
131 init_list(&tmp_list);
132 add_tail_list(&tmp_list, l);
133 init_list(l);
b933281e 134 WALK_LIST_FIRST(n, tmp_list)
3b15402f 135 {
0d70292d 136 event *e = SKIP_BACK(event, n, n);
8bcb5fb1
OZ
137
138 /* This is ugly hack, we want to log just events executed from the main I/O loop */
139 if (l == &global_event_list)
140 io_log_event(e->hook, e->data);
141
ebc793a5 142 ev_run(e);
3b15402f 143 }
ebc793a5 144 return !EMPTY_LIST(*l);
3b15402f 145}