blob: ba1555ae6fc4ab4d2373af4080296d9b18cc0c7f [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file signal.c
2 * Generic signalling/notification infrastructure. */
3/*
4 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
Harald Welteec8b4502010-02-20 20:34:29 +01005 * All Rights Reserved
6 *
Harald Weltee08da972017-11-13 01:00:26 +09007 * SPDX-License-Identifier: GPL-2.0+
8 *
Harald Welteec8b4502010-02-20 20:34:29 +01009 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
Harald Welteec8b4502010-02-20 20:34:29 +010019 */
20
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010021#include <osmocom/core/signal.h>
22#include <osmocom/core/talloc.h>
23#include <osmocom/core/linuxlist.h>
Harald Welteec8b4502010-02-20 20:34:29 +010024#include <stdlib.h>
25#include <string.h>
26#include <errno.h>
27
Harald Welteaf8e4352011-08-17 16:19:46 +020028/*! \addtogroup signal
29 * @{
Neels Hofmeyr17518fe2017-06-20 04:35:06 +020030 * Generic signalling/notification infrastructure.
31 *
32 * \file signal.c */
Harald Welteaf8e4352011-08-17 16:19:46 +020033
34
Oliver Smith9f281422019-03-22 13:22:46 +010035void *tall_sigh_ctx;
Harald Welteec8b4502010-02-20 20:34:29 +010036static LLIST_HEAD(signal_handler_list);
37
38struct signal_handler {
39 struct llist_head entry;
40 unsigned int subsys;
Pablo Neira Ayusoa10dd352011-05-07 12:42:45 +020041 osmo_signal_cbfn *cbfn;
Harald Welteec8b4502010-02-20 20:34:29 +010042 void *data;
43};
44
Pau Espin Pedrol0b6fcb02018-08-16 19:05:19 +020045/*! Initialize a signal_handler talloc context for \ref osmo_signal_register_handler.
46 * Create a talloc context called "osmo_signal".
47 * \param[in] root_ctx talloc context used as parent for the new "osmo_signal" ctx.
48 * \returns the new osmo_signal talloc context, e.g. for reporting
49 */
50void *osmo_signal_talloc_ctx_init(void *root_ctx) {
Harald Welte8c58af12019-03-20 11:26:58 +010051 tall_sigh_ctx = talloc_named_const(root_ctx, 0, "osmo_signal");
Pau Espin Pedrol0b6fcb02018-08-16 19:05:19 +020052 return tall_sigh_ctx;
53}
Harald Welteec8b4502010-02-20 20:34:29 +010054
Neels Hofmeyr87e45502017-06-20 00:17:59 +020055/*! Register a new signal handler
Harald Welteaf8e4352011-08-17 16:19:46 +020056 * \param[in] subsys Subsystem number
57 * \param[in] cbfn Callback function
58 * \param[in] data Data passed through to callback
Harald Welte2d2e2cc2016-04-25 12:11:20 +020059 * \returns 0 on success; negative in case of error
Harald Welteaf8e4352011-08-17 16:19:46 +020060 */
Pablo Neira Ayusoa10dd352011-05-07 12:42:45 +020061int osmo_signal_register_handler(unsigned int subsys,
62 osmo_signal_cbfn *cbfn, void *data)
Harald Welteec8b4502010-02-20 20:34:29 +010063{
64 struct signal_handler *sig_data;
65
Vadim Yanitskiya3226f72019-03-20 20:41:54 +070066 sig_data = talloc_zero(tall_sigh_ctx, struct signal_handler);
Harald Welteec8b4502010-02-20 20:34:29 +010067 if (!sig_data)
68 return -ENOMEM;
69
Harald Welteec8b4502010-02-20 20:34:29 +010070 sig_data->subsys = subsys;
71 sig_data->data = data;
72 sig_data->cbfn = cbfn;
73
74 /* FIXME: check if we already have a handler for this subsys/cbfn/data */
75
76 llist_add_tail(&sig_data->entry, &signal_handler_list);
77
78 return 0;
79}
80
Neels Hofmeyr87e45502017-06-20 00:17:59 +020081/*! Unregister signal handler
Harald Welteaf8e4352011-08-17 16:19:46 +020082 * \param[in] subsys Subsystem number
83 * \param[in] cbfn Callback function
84 * \param[in] data Data passed through to callback
85 */
Pablo Neira Ayusoa10dd352011-05-07 12:42:45 +020086void osmo_signal_unregister_handler(unsigned int subsys,
87 osmo_signal_cbfn *cbfn, void *data)
Harald Welteec8b4502010-02-20 20:34:29 +010088{
89 struct signal_handler *handler;
90
91 llist_for_each_entry(handler, &signal_handler_list, entry) {
92 if (handler->cbfn == cbfn && handler->data == data
93 && subsys == handler->subsys) {
94 llist_del(&handler->entry);
95 talloc_free(handler);
96 break;
97 }
98 }
99}
100
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200101/*! dispatch (deliver) a new signal to all registered handlers
Harald Welteaf8e4352011-08-17 16:19:46 +0200102 * \param[in] subsys Subsystem number
103 * \param[in] signal Signal number,
104 * \param[in] signal_data Data to be passed along to handlers
105 */
Pablo Neira Ayusoa10dd352011-05-07 12:42:45 +0200106void osmo_signal_dispatch(unsigned int subsys, unsigned int signal,
107 void *signal_data)
Harald Welteec8b4502010-02-20 20:34:29 +0100108{
109 struct signal_handler *handler;
110
111 llist_for_each_entry(handler, &signal_handler_list, entry) {
112 if (handler->subsys != subsys)
113 continue;
114 (*handler->cbfn)(subsys, signal, handler->data, signal_data);
115 }
116}
Harald Welteaf8e4352011-08-17 16:19:46 +0200117
Sylvain Munautdca7d2c2012-04-18 21:53:23 +0200118/*! @} */