Commit 9d27e7c9 authored by Maria Matejka's avatar Maria Matejka
Browse files

Notify: Also the listener list is typed.

parent bb623f0a
Loading
Loading
Loading
Loading

lib/tlists.h

0 → 100644
+61 −0
Original line number Diff line number Diff line
/*
 *	BIRD Library -- Typed Linked Lists
 *
 *	(c) 2019 Maria Matejka <mq@jmq.cz>
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 *
 *	Based roughly on Martin Mares' lib/lists.h but completely implemented as macros.
 */

#ifndef _BIRD_TLISTS_H_
#define _BIRD_TLISTS_H_

#define TNODE(t) struct tnode__##t
#define TNODE_DEF(t)
#define TLIST(t) union tlist__##t
#define TLIST_DEF(t) TNODE(t) { \
  TNODE(t) *next; \
  struct t *self; \
  TNODE(t) *prev; \
}; \
  TLIST(t) { \
  struct { \
    TNODE(t) head_node; \
    struct t *head_null_self; \
    TNODE(t) *tail; \
  }; \
  struct { \
    TNODE(t) *head; \
    struct t *tail_padding_self; \
    TNODE(t) tail_node; \
  }; \
}

#define INIT_TLIST(t, list) do { \
  memset(&(list), 0, sizeof(TLIST(t))); \
  list.head_node.next = &(list.tail_node); \
  list.tail_node.prev = &(list.head_node); \
} while (0)

#define TNODE_VALID(t, n) ((n)->next)
#define WALK_TLIST(t, n, list) for (TNODE(t) *n = list.head; TNODE_VALID(t, n); n = n->next)
#define WALK_TLIST_DELSAFE(t, n, list) \
  for (TNODE(t) *n = list.head, *_n; _n = n->next; n = _n)

#define TADD_TAIL(t, list, node) do { \
  TNODE(t) *p = list.tail; \
  node.prev = p; \
  node.next = &(list.tail_node); \
  p->next = &(node); \
  list.tail = &(node); \
} while (0)

#define TREM_NODE(t, node) do { \
  TNODE(t) *p = node.prev, *n = node.next; \
  node.prev = node.next = NULL; \
  p->next = n; \
  n->prev = p; \
} while (0)

#endif
+1 −1
Original line number Diff line number Diff line
src := a-path.c a-set.c cli.c cmds.c iface.c locks.c neighbor.c notify.c password.c proto.c rt-attr.c rt-dev.c rt-fib.c rt-show.c rt-table.c
src := a-path.c a-set.c cli.c cmds.c iface.c locks.c neighbor.c password.c proto.c rt-attr.c rt-dev.c rt-fib.c rt-show.c rt-table.c
obj := $(src-o-files)
$(all-daemon)
$(cf-local)

nest/notify.c

deleted100644 → 0
+0 −30
Original line number Diff line number Diff line
/*
 *	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.
 */

#include "nest/bird.h"
#include "lib/resource.h"
#include "nest/notify.h"

LISTENER_DECL(void);

static void
listener_unsubscribe(resource *r)
{
  LISTENER(void) *L = (LISTENER(void) *) r;
  rem_node(&(L->n));
  CALL(L->unsubscribe, L->self);
}

struct resclass listener_class = {
  .name = "Listener",
  .size = sizeof(LISTENER(void)),
  .free = listener_unsubscribe,
  .dump = NULL,
  .lookup = NULL,
  .memsize = NULL,
};
+29 −15
Original line number Diff line number Diff line
@@ -10,25 +10,43 @@
#define _BIRD_NOTIFY_H_

#include "lib/resource.h"
#include "lib/lists.h"
#include "lib/tlists.h"

#define LISTENER(stype) struct listener__##stype
#define LISTENER_DECL(stype) LISTENER(stype) { \
#define LISTENER_DEF(stype) \
  TLIST_DEF(listener__##stype); \
LISTENER(stype) { \
  resource r; \
  node n; \
  TNODE(listener__##stype) n; \
  void *self; \
  void (*unsubscribe)(void *self); \
  void (*notify)(void *self, const stype *data); \
};
}; \
extern struct resclass LISTENER_CLASS(stype) 

extern struct resclass listener_class;
#define LISTENERS(stype) TLIST(listener__##stype)

#define LISTENER_CLASS(stype) listener_class__##stype
#define LISTENER_CLASS_DEF(stype) static void listener_unsubscribe__##stype(resource *r) { \
  LISTENER(stype) *L = (LISTENER(stype) *) r; \
  TREM_NODE(listener__##stype, L->n); \
  CALL(L->unsubscribe, L->self); \
} \
struct resclass LISTENER_CLASS(stype) = { \
  .name = "Listener " #stype, \
  .size = sizeof(LISTENER(stype)), \
  .free = listener_unsubscribe__##stype, \
}

#define INIT_LISTENERS(stype, sender) INIT_TLIST(listener__##stype, sender)

#define SUBSCRIBE(stype, pool, sender, _self, _notify, _unsubscribe) ({ \
    LISTENER(stype) *L = ralloc(pool, &listener_class); \
    LISTENER(stype) *L = ralloc(pool, &listener_class__##stype); \
    L->notify = _notify; \
    L->unsubscribe = _unsubscribe; \
    L->self = _self; \
    add_tail(&(sender), &(L->n)); \
    L->n.self = L; \
    TADD_TAIL(listener__##stype, sender, L->n); \
    L; \
    })

@@ -39,18 +57,14 @@ extern struct resclass listener_class;
} while (0)

#define UNNOTIFY(stype, sender) do { \
  LISTENER(stype) *L; \
  node *x, *y; \
  WALK_LIST2_DELSAFE(L, x, y, sender, n) \
    rfree(L); \
  WALK_TLIST_DELSAFE(listener__##stype, L, sender) \
    rfree(L->self); \
} 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); \
  WALK_TLIST_DELSAFE(listener__##stype, L, sender) \
    L->self->notify(L->self->self, _d); \
} while (0)

#endif
+4 −3
Original line number Diff line number Diff line
@@ -146,12 +146,15 @@ struct rtable_config {
  byte sorted;				/* Routes of network are sorted according to rte_better() */
};

typedef struct rt_notify rt_notify_data;
LISTENER_DEF(rt_notify_data);

typedef struct rtable {
  node n;				/* Node in list of all tables */
  struct fib fib;
  char *name;				/* Name of this table */
  list channels;			/* List of attached channels (struct channel) */
  list listeners;			/* List of attached listeners (struct listener) */
  LISTENERS(rt_notify_data) listeners;	/* List of attached listeners */
  uint addr_type;			/* Type of address data stored in table (NET_*) */
  int pipe_busy;			/* Pipe loop detection */
  int use_count;			/* Number of protocols using this table */
@@ -327,8 +330,6 @@ typedef struct rt_notify {
  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 */
extern const int rt_default_ecmp;

Loading