blob: d4a4a7ce25016dc70d9d880880150b869dbb8bcb [file] [log] [blame]
Holger Freyther2b2d2e32009-02-14 22:51:00 +00001/* Generic signalling/notification infrastructure */
2/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */
20
21#include <openbsc/signal.h>
22#include <malloc.h>
23#include <string.h>
24
25
26static LLIST_HEAD(signal_handler_list);
27
28struct signal_handler {
29 struct llist_head entry;
30 int areas;
31
32 int (*sig_handler)(struct signal_data *, void*);
33 void *data;
34};
35
36
37void register_signal_handler(int areas,
38 int (*handler)(struct signal_data *, void *), void *data)
39{
40 struct signal_handler *sig_data =
41 (struct signal_handler *)malloc(sizeof(*sig_data));
42 memset(sig_data, 0, sizeof(*sig_data));
43
44
45 sig_data->areas = areas;
46 sig_data->data = data;
47 sig_data->sig_handler = handler;
48 llist_add_tail(&signal_handler_list, &sig_data->entry);
49}
50
51void remove_signal_handler(int (*sig_handler)(struct signal_data *, void *), void *data)
52{
53 struct signal_handler *handler;
54
55 llist_for_each_entry(handler, &signal_handler_list, entry) {
56 if (handler->sig_handler == sig_handler && handler->data == data) {
57 llist_del(&handler->entry);
58 free(handler);
59 break;
60 }
61 }
62}
63
64
65void dispatch_signal(int area, struct signal_data *data)
66{
67 struct signal_handler *handler;
68
69 llist_for_each_entry(handler, &signal_handler_list, entry) {
70 if (handler->areas & area) {
71 (*handler->sig_handler)(data, handler->data);
72 }
73 }
74}