mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-11 03:21:53 +00:00
Subscribe/Notify: The notification data is typed.
This commit is contained in:
parent
370958afc2
commit
bb623f0ae3
@ -55,12 +55,12 @@ void (*bt_assert_hook)(int result, struct f_inst *assert);
|
|||||||
|
|
||||||
struct filter_roa_reloader {
|
struct filter_roa_reloader {
|
||||||
node n;
|
node n;
|
||||||
struct listener *L;
|
LISTENER(rt_notify_data) *L;
|
||||||
struct rtable *roa_table;
|
struct rtable *roa_table;
|
||||||
struct filter_slot *slot;
|
struct filter_slot *slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void filter_roa_reloader_notify(void *self, const void *data UNUSED) {
|
static void filter_roa_reloader_notify(void *self, const rt_notify_data *data UNUSED) {
|
||||||
struct filter_roa_reloader *frr = self;
|
struct filter_roa_reloader *frr = self;
|
||||||
frr->slot->reloader(frr->slot);
|
frr->slot->reloader(frr->slot);
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ static void filter_roa_reloader_subscribe(struct rtable *roa_table, struct filte
|
|||||||
frr->roa_table = roa_table;
|
frr->roa_table = roa_table;
|
||||||
frr->slot = slot;
|
frr->slot = slot;
|
||||||
add_tail(&(slot->notifiers), &(frr->n));
|
add_tail(&(slot->notifiers), &(frr->n));
|
||||||
frr->L = subscribe(slot->p, &(roa_table->listeners), filter_roa_reloader_notify, filter_roa_reloader_unsubscribe, frr);
|
frr->L = SUBSCRIBE(rt_notify_data, slot->p, roa_table->listeners, frr, filter_roa_reloader_notify, filter_roa_reloader_unsubscribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct adata undef_adata; /* adata of length 0 used for undefined */
|
static struct adata undef_adata; /* adata of length 0 used for undefined */
|
||||||
|
@ -10,63 +10,21 @@
|
|||||||
#include "lib/resource.h"
|
#include "lib/resource.h"
|
||||||
#include "nest/notify.h"
|
#include "nest/notify.h"
|
||||||
|
|
||||||
struct listener {
|
LISTENER_DECL(void);
|
||||||
resource r;
|
|
||||||
node n;
|
|
||||||
|
|
||||||
void (*notify)(void *self, const void *data);
|
|
||||||
void (*unsubscribe)(void *self);
|
|
||||||
|
|
||||||
void *self;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
listener_unsubscribe(resource *r)
|
listener_unsubscribe(resource *r)
|
||||||
{
|
{
|
||||||
struct listener *L = (struct listener *) r;
|
LISTENER(void) *L = (LISTENER(void) *) r;
|
||||||
rem_node(&(L->n));
|
rem_node(&(L->n));
|
||||||
CALL(L->unsubscribe, L->self);
|
CALL(L->unsubscribe, L->self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resclass listener_class = {
|
struct resclass listener_class = {
|
||||||
.name = "Listener",
|
.name = "Listener",
|
||||||
.size = sizeof(struct listener),
|
.size = sizeof(LISTENER(void)),
|
||||||
.free = listener_unsubscribe,
|
.free = listener_unsubscribe,
|
||||||
.dump = NULL,
|
.dump = NULL,
|
||||||
.lookup = NULL,
|
.lookup = NULL,
|
||||||
.memsize = NULL,
|
.memsize = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct listener *
|
|
||||||
subscribe(pool *p, list *sender, void (*notify)(void *, const void *), void (*unsubscribe)(void *), void *self)
|
|
||||||
{
|
|
||||||
struct listener *L = ralloc(p, &listener_class);
|
|
||||||
L->notify = notify;
|
|
||||||
L->unsubscribe = unsubscribe;
|
|
||||||
L->self = self;
|
|
||||||
|
|
||||||
add_tail(sender, &(L->n));
|
|
||||||
return L;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unsubscribe(struct listener *L)
|
|
||||||
{
|
|
||||||
L->unsubscribe = NULL;
|
|
||||||
rfree(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unsubscribe_all(list *sender)
|
|
||||||
{
|
|
||||||
struct listener *L;
|
|
||||||
node *x, *y;
|
|
||||||
WALK_LIST2_DELSAFE(L, x, y, *sender, n)
|
|
||||||
rfree(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
void notify(list *sender, const void *data)
|
|
||||||
{
|
|
||||||
struct listener *L;
|
|
||||||
node *x, *y;
|
|
||||||
WALK_LIST2_DELSAFE(L, x, y, *sender, n)
|
|
||||||
L->notify(L->self, data);
|
|
||||||
}
|
|
||||||
|
@ -12,11 +12,45 @@
|
|||||||
#include "lib/resource.h"
|
#include "lib/resource.h"
|
||||||
#include "lib/lists.h"
|
#include "lib/lists.h"
|
||||||
|
|
||||||
struct listener;
|
#define LISTENER(stype) struct listener__##stype
|
||||||
|
#define LISTENER_DECL(stype) LISTENER(stype) { \
|
||||||
|
resource r; \
|
||||||
|
node n; \
|
||||||
|
void *self; \
|
||||||
|
void (*unsubscribe)(void *self); \
|
||||||
|
void (*notify)(void *self, const stype *data); \
|
||||||
|
};
|
||||||
|
|
||||||
struct listener *subscribe(pool *p, list *sender, void (*notify)(void *self, const void *data), void (*unsubscribe)(void *self), void *self);
|
extern struct resclass listener_class;
|
||||||
void unsubscribe(struct listener *L);
|
|
||||||
void unsubscribe_all(list *sender);
|
#define SUBSCRIBE(stype, pool, sender, _self, _notify, _unsubscribe) ({ \
|
||||||
void notify(list *sender, const void *data);
|
LISTENER(stype) *L = ralloc(pool, &listener_class); \
|
||||||
|
L->notify = _notify; \
|
||||||
|
L->unsubscribe = _unsubscribe; \
|
||||||
|
L->self = _self; \
|
||||||
|
add_tail(&(sender), &(L->n)); \
|
||||||
|
L; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define UNSUBSCRIBE(stype, listener) do { \
|
||||||
|
LISTENER(stype) *L = listener; \
|
||||||
|
L->unsubscribe = NULL; \
|
||||||
|
rfree(L); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define UNNOTIFY(stype, sender) do { \
|
||||||
|
LISTENER(stype) *L; \
|
||||||
|
node *x, *y; \
|
||||||
|
WALK_LIST2_DELSAFE(L, x, y, sender, n) \
|
||||||
|
rfree(L); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define NOTIFY(stype, sender, data) do { \
|
||||||
|
const stype *_d = data; \
|
||||||
|
LISTENER(stype) *L; \
|
||||||
|
node *x, *y; \
|
||||||
|
WALK_LIST2_DELSAFE(L, x, y, sender, n) \
|
||||||
|
L->notify(L->self, _d); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include "lib/resource.h"
|
#include "lib/resource.h"
|
||||||
#include "lib/net.h"
|
#include "lib/net.h"
|
||||||
|
|
||||||
|
#include "nest/notify.h"
|
||||||
|
|
||||||
struct ea_list;
|
struct ea_list;
|
||||||
struct protocol;
|
struct protocol;
|
||||||
struct proto;
|
struct proto;
|
||||||
@ -320,10 +322,12 @@ void rt_reload_channel_abort(struct channel *c);
|
|||||||
void rt_prune_sync(rtable *t, int all);
|
void rt_prune_sync(rtable *t, int all);
|
||||||
struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
|
struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
|
||||||
|
|
||||||
struct rt_notify {
|
typedef struct rt_notify {
|
||||||
struct network *net;
|
struct network *net;
|
||||||
rte *new, *old, *new_best, *old_best, *before_old;
|
rte *new, *old, *new_best, *old_best, *before_old;
|
||||||
};
|
} rt_notify_data;
|
||||||
|
|
||||||
|
LISTENER_DECL(rt_notify_data);
|
||||||
|
|
||||||
/* Default limit for ECMP next hops, defined in sysdep code */
|
/* Default limit for ECMP next hops, defined in sysdep code */
|
||||||
extern const int rt_default_ecmp;
|
extern const int rt_default_ecmp;
|
||||||
|
@ -951,7 +951,7 @@ rte_announce(rtable *tab, unsigned type, net *net, rte *new, rte *old,
|
|||||||
.before_old = before_old,
|
.before_old = before_old,
|
||||||
};
|
};
|
||||||
|
|
||||||
notify(&(tab->listeners), &rtn);
|
NOTIFY(rt_notify_data, tab->listeners, &rtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@ -2173,6 +2173,7 @@ rt_unlock_table(rtable *r)
|
|||||||
r->config->table = NULL;
|
r->config->table = NULL;
|
||||||
if (r->hostcache)
|
if (r->hostcache)
|
||||||
rt_free_hostcache(r);
|
rt_free_hostcache(r);
|
||||||
|
UNNOTIFY(rt_notify_data, r->listeners);
|
||||||
rem_node(&r->n);
|
rem_node(&r->n);
|
||||||
fib_free(&r->fib);
|
fib_free(&r->fib);
|
||||||
rfree(r->rt_event);
|
rfree(r->rt_event);
|
||||||
|
Loading…
Reference in New Issue
Block a user