summaryrefslogtreecommitdiffstats
path: root/ffd/update.c
diff options
context:
space:
mode:
Diffstat (limited to 'ffd/update.c')
-rw-r--r--ffd/update.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/ffd/update.c b/ffd/update.c
index 5ae3006..d273fec 100644
--- a/ffd/update.c
+++ b/ffd/update.c
@@ -35,18 +35,18 @@
static ffd_queue_t *pending_updates = NULL;
-typedef struct _update_arg {
+typedef struct _update_arg_t {
ffd_node_id_t node;
uint16_t type;
uint16_t key;
ffd_neigh_t *neigh;
unsigned ref;
-} update_arg;
+} update_arg_t;
-static inline update_arg* update_new(const ffd_node_id_t *node, uint16_t type, uint16_t key, ffd_neigh_t *neigh) {
- update_arg *arg = malloc(sizeof(update_arg));
+static inline update_arg_t* update_new(const ffd_node_id_t *node, uint16_t type, uint16_t key, ffd_neigh_t *neigh) {
+ update_arg_t *arg = malloc(sizeof(update_arg_t));
arg->node = *node;
arg->type = type;
@@ -61,12 +61,12 @@ static inline update_arg* update_new(const ffd_node_id_t *node, uint16_t type, u
return arg;
}
-static inline update_arg* update_ref(update_arg *arg) {
+static inline update_arg_t* update_ref(update_arg_t *arg) {
arg->ref++;
return arg;
}
-static inline void update_unref(update_arg *arg) {
+static inline void update_unref(update_arg_t *arg) {
if (!--arg->ref) {
if (arg->neigh)
ffd_neigh_unref(arg->neigh);
@@ -79,7 +79,7 @@ void ffd_update_enqueue(const ffd_node_id_t *node, uint16_t type, uint16_t key,
if (neigh)
ffd_neigh_ref(neigh);
- update_arg *arg = update_new(node, type, key, neigh);
+ update_arg_t *arg = update_new(node, type, key, neigh);
if (urgent) {
ffd_queue_put_delayed(&pending_updates, NULL, &now, FFD_URGENT_DELAY, update_ref(arg));
@@ -99,19 +99,36 @@ int ffd_update_timeout(void) {
void ffd_update_run(void) {
while (!ffd_update_timeout()) {
- update_arg *arg = pending_updates->arg;
+ ffd_neigh_t *neigh = ((update_arg_t*)pending_updates->arg)->neigh;
- ffd_neigh_t *neigh = arg->neigh;
- ffd_announce_t *announce = ffd_announce_find(&arg->node, arg->type, arg->key);
+ ffd_update_t *update = ffd_send_update_new(NULL, neigh);
- fprintf(stderr, "debug: sending scheduled update.\n");
+ fprintf(stderr, "debug: sending scheduled updates.\n");
- if (announce)
- ffd_send_update(NULL, neigh, announce, false);
- else
- ffd_send_retract(neigh, arg->node, arg->type, arg->key);
+ ffd_queue_t **entry;
+ for (entry = &pending_updates; *entry;) {
+ update_arg_t *arg = (*entry)->arg;
- update_unref(arg);
- ffd_queue_drop(&pending_updates);
+ if (arg->neigh != neigh) {
+ entry = &(*entry)->next;
+ continue;
+ }
+
+ ffd_announce_t *announce = ffd_announce_find(&arg->node, arg->type, arg->key);
+ bool ret;
+
+ if (announce)
+ ret = ffd_send_update_add(update, announce);
+ else
+ ret = ffd_send_update_retract(update, arg->node, arg->type, arg->key);
+
+ if (!ret)
+ break;
+
+ update_unref(arg);
+ ffd_queue_drop(entry);
+ }
+
+ ffd_send_update_finish(update);
}
}