mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-25 11:11:53 +00:00
f827cf11be
This implementation will just automatically request channel reload/refeed when ROA change is detected. It may be sufficient for many uses; performance impact for big IXPs is unclear.
89 lines
1.9 KiB
C
89 lines
1.9 KiB
C
/*
|
|
* BIRD Internet Routing Daemon -- Notificators and Listeners
|
|
*
|
|
* (c) 2019 Maria Matejka <mq@jmq.cz>
|
|
*
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
*/
|
|
|
|
#ifndef _BIRD_NOTIFY_H_
|
|
#define _BIRD_NOTIFY_H_
|
|
|
|
#include "lib/lists.h"
|
|
|
|
struct listener {
|
|
node sender_node;
|
|
node receiver_node;
|
|
|
|
void (*hook)(struct listener *who, void *data);
|
|
void (*dump)(struct listener *who);
|
|
void (*unsub)(struct listener *who);
|
|
};
|
|
|
|
static inline void subscribe(struct listener *who, list *sender, list *receiver)
|
|
{
|
|
ASSERT(!NODE_VALID(&(who->sender_node)));
|
|
ASSERT(!NODE_VALID(&(who->receiver_node)));
|
|
|
|
add_tail(sender, &(who->sender_node));
|
|
add_tail(receiver, &(who->receiver_node));
|
|
}
|
|
|
|
static inline void unsubscribe(struct listener *who)
|
|
{
|
|
/* Allow multiple unsubscribe */
|
|
if (!NODE_VALID(&(who->sender_node))
|
|
&& !NODE_VALID(&(who->receiver_node)))
|
|
return;
|
|
|
|
ASSERT(NODE_VALID(&(who->sender_node))
|
|
&& NODE_VALID(&(who->receiver_node)));
|
|
|
|
rem_node(&(who->sender_node));
|
|
rem_node(&(who->receiver_node));
|
|
|
|
who->sender_node = who->receiver_node = (node) {};
|
|
CALL(who->unsub, who);
|
|
}
|
|
|
|
static inline void unsubscribe_all(list *receiver)
|
|
{
|
|
struct listener *n;
|
|
node *x, *y;
|
|
WALK_LIST2_DELSAFE(n, x, y, *receiver, receiver_node)
|
|
unsubscribe(n);
|
|
}
|
|
|
|
static inline void notify(list *sender, void *data)
|
|
{
|
|
struct listener *n;
|
|
node *x, *y;
|
|
WALK_LIST2_DELSAFE(n, x, y, *sender, sender_node)
|
|
n->hook(n, data);
|
|
}
|
|
|
|
static inline void listeners_dump(list *sender, list *receiver)
|
|
{
|
|
ASSERT((!sender) || (!receiver));
|
|
ASSERT(sender || receiver);
|
|
|
|
struct listener *n;
|
|
node *x;
|
|
if (sender)
|
|
WALK_LIST2(n, x, *sender, sender_node) {
|
|
debug("\t\tNotifier: hook %p", n->hook);
|
|
CALL(n->dump, n);
|
|
debug("\n");
|
|
}
|
|
|
|
if (receiver)
|
|
WALK_LIST2(n, x, *receiver, receiver_node) {
|
|
debug("\t\tNotifier: hook %p", n->hook);
|
|
CALL(n->dump, n);
|
|
debug("\n");
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|