]> jfr.im git - irc/rakaur/praxis.git/blame - src/core/event.c
Fixes from clang warnings.
[irc/rakaur/praxis.git] / src / core / event.c
CommitLineData
9af9ec33
EW
1/* praxis: services for TSora IRC networks.
2 * src/event.c: The event loop routines.
3 *
4 * Copyright (c) 2004 Eric Will <rakaur@malkier.net>
5 * Copyright (c) 2003-2004 shrike development team.
6 *
7 * $Id$
8 */
9
10#include "praxis.h"
11#include "dlink.h"
12#include "balloc.h"
13#include "ilog.h"
14#include "events.h"
15#include "event.h"
16
17static Heap *eventq_heap;
18
19/* eventInit()
20 * Initialises the event system.
21 *
22 * inputs - none
23 * outputs - none
24 */
25void
26eventInit(void)
27{
28 eventq_heap = ballocHeapCreate(sizeof(EventQ), EVENTQ_HEAP_SIZE);
29
30 memset(&event_table, '\0', (sizeof(Event) * E_LAST));
31 memset(&event_queue, '\0', sizeof(event_queue));
32
33 if (eventq_heap == NULL)
34 {
35 ilog(L_INFO, "eventInit(): ballocHeapCreate() failed!");
36 exit(EXIT_FAILURE);
37 }
38}
39
40/* eventAdd()
41 * Adds a function to be called when an event happens.
42 *
43 * inputs - E_event, pointer to function
44 * outputs - none
45 */
46void
47eventAdd(uint event, uchar (*func) ())
48{
49 iassert(event >= 0);
50 iassert(event < E_LAST);
51 iassert(func != NULL);
52
53 ilog(L_DEBUG2, "eventAdd(): Registering function for event: %d", event);
54
512f83e1 55 dlinkAddTailAlloc((void *)func, &event_table[event].func_list);
9af9ec33
EW
56}
57
58/* eventAddSpecial()
59 * Adds a function to be called first or last when an event happens.
60 *
61 * inputs - E_event, 1 for first 2 for last, pointer to function
62 * outputs - 1 on success or 0 on failure
63 */
64uchar
65eventAddSpecial(uint event, uchar type, uchar (*func) ())
66{
67 iassert(event >= 0);
68 iassert(event < E_LAST);
69 iassert(type == 1 || type == 2);
70 iassert(func != NULL);
71
72 if (type == 1)
73 {
74 if (event_table[event].first_func != NULL)
75 return 0;
76
77 ilog(L_DEBUG2, "eventAddSpecial(): Registering first function for "
78 "event: %d", event);
79
80 event_table[event].first_func = func;
81 }
82 else if (type == 2)
83 {
84 if (event_table[event].last_func != NULL)
85 return 0;
86
87 ilog(L_DEBUG2, "eventAddSpecial(): Registering last function for "
88 "event: %d", event);
89
90 event_table[event].last_func = func;
91 }
92 else
93 return 0;
94
95 return 1;
96}
97
98/* eventDelete()
99 * Removes a function to be called when an event happens.
100 *
101 * inputs - E_event, pointer to function
102 * outputs - 1 on success or 0 on failure
103 */
104uchar
105eventDelete(uint event, uchar (*func) ())
106{
107 uchar ret;
108
109 iassert(event >= 0);
110 iassert(event < E_LAST);
111 iassert(func != NULL);
112
113 ilog(L_DEBUG2, "eventDelete(): Unregistering function for event: %d",
114 event);
115
512f83e1 116 ret = dlinkFindDestroy((void *)func, &event_table[event].func_list);
9af9ec33
EW
117
118 if (ret == 0)
119 {
120 ilog(L_ERROR, "eventDelete(): dlinkFindDestroy() failed.");
121 return 0;
122 }
123
124 return 1;
125}
126
127/* eventDeleteSpecial()
128 * Removes a function to be called first or last when an event happens.
129 *
130 * inputs - E_event, 1 for first 2 for last, pointer to function
131 * outputs - 1 on success or 0 on failure
132 */
133uchar
134eventDeleteSpecial(uint event, uchar type, uchar (*func) ())
135{
136 iassert(event >= 0);
137 iassert(event < E_LAST);
138 iassert(type == 1 || type == 2);
139 iassert(func != NULL);
140
141 if (type == 1)
142 {
143 if (event_table[event].first_func != func)
144 return 0;
145
146 ilog(L_DEBUG2, "eventDeleteSpecial(): Unregistering first function for "
147 "event: %d", event);
148
149 event_table[event].first_func = NULL;
150 }
151 else if (type == 2)
152 {
153 if (event_table[event].last_func != func)
154 return 0;
155
156 ilog(L_DEBUG2, "eventDeleteSpecial(): Unregistering last function for "
157 "event: %d", event);
158
159 event_table[event].last_func = NULL;
160 }
161 else
162 return 0;
163
164 return 1;
165}
166
167/* eventPost()
168 * Post an event to the event_queue that has happened.
169 *
170 * inputs - E_event, argument
171 * outputs - none
172 */
173void
174eventPost(uint event, void *arg)
175{
176 EventQ *eventq_p;
177
178 iassert(event >= 0);
179 iassert(event < E_LAST);
180
181 /* Check to see if this Event is being handled. */
182 if ((event_table[event].first_func == NULL) &&
183 (dlinkLength(&event_table[event].func_list) == 0) &&
184 (event_table[event].last_func == NULL))
185 return;
186
187 eventq_p = ballocHeapAlloc(eventq_heap);
188
189 eventq_p->event = event;
190 eventq_p->arg = arg;
191
192 dlinkAddTailAlloc(eventq_p, &event_queue);
193}
194
195/* eventShouldRun()
196 * Returns if we need to clear the queue or not.
197 *
198 * inputs - none
199 * outputs - 1 for yes, or 0 for no
200 */
201uchar
202eventShouldRun(void)
203{
204 if (dlinkLength(&event_queue) != 0)
205 return 1;
206
207 return 0;
208}
209
210/* eventRun()
211 * Runs all pending events.
212 *
213 * inputs - none
214 * outputs - none
215 */
216void
217eventRun(void)
218{
219 EventQ *eventq_p;
220 DLinkNode *node_p, *tnode_p, *node2_p;
221 uchar (*func) ();
222 uchar ret, terminated = 0;
223
224 /* Should we even bother? */
225 if (dlinkLength(&event_queue) == 0)
226 return;
227
228 DLINK_FOREACH_SAFE(node_p, tnode_p, event_queue.head)
229 {
230 eventq_p = node_p->data;
231
232 /* If there's a first function, call it. */
233 if (event_table[eventq_p->event].first_func != NULL)
234 {
235 ret = event_table[eventq_p->event].first_func(eventq_p->arg);
236
237 if (ret == 0)
238 {
239 ilog(L_ERROR, "eventRun(): first_func failure for event: %d.",
240 eventq_p->event);
241
242 terminated = 1;
243 }
244 }
245
246 /* If there are function list entries, call them. */
247 DLINK_FOREACH(node2_p, event_table[eventq_p->event].func_list.head)
248 {
512f83e1 249 func = (uchar (*) ())node2_p->data;
9af9ec33
EW
250
251 if (terminated == 1)
252 break;
253
254 ret = func(eventq_p->arg);
255
256 if (ret == 0)
257 {
258 ilog(L_ERROR, "eventRun(): func_list failure for event: %d.",
259 eventq_p->event);
260
261 terminated = 1;
262 }
263 }
264
265 /* If there's a last function, call it. */
266 if (event_table[eventq_p->event].last_func != NULL)
267 {
268 ret = event_table[eventq_p->event].last_func(eventq_p->arg);
269
270 if (ret == 0)
271 {
272 ilog(L_ERROR, "eventRun(): last_func failure for event: %d.",
273 eventq_p->event);
274 }
275 }
276
277 /* Now destroy the event_queue entry. */
278 dlinkDestroy(node_p, &event_queue);
279 ballocHeapFree(eventq_heap, eventq_p);
280 }
281}