add a clean lock/unlock model for nbr2 references
authorHannes Gredler <hannes@gredler.at>
Wed, 27 May 2009 08:38:58 +0000 (10:38 +0200)
committerHannes Gredler <hannes@gredler.at>
Wed, 27 May 2009 08:38:58 +0000 (10:38 +0200)
src/mpr.c
src/neighbor_table.c
src/process_package.c
src/two_hop_neighbor_table.c
src/two_hop_neighbor_table.h

index c5ddf87..e4b98cd 100644 (file)
--- a/src/mpr.c
+++ b/src/mpr.c
@@ -360,7 +360,7 @@ olsr_calculate_mpr(void)
       /*
        * Eliminate 2 hop neighbors which are not single link.
        */
-      if (nbr2->nbr2_pointer != 1) {
+      if (nbr2->nbr2_refcount != 1) {
         OLSR_DEBUG(LOG_MPR, "Skipping 2-hop neighbor %s - not single link\n",
                    olsr_ip_to_string(&buf, &nbr2->nbr2_addr));
         continue;
index 2b6a079..c1121f5 100644 (file)
@@ -108,8 +108,9 @@ olsr_add_nbr2_list_entry(struct nbr_entry *nbr, struct nbr2_entry *nbr2, float v
   nbr2_list = olsr_cookie_malloc(nbr2_list_mem_cookie);
 
   nbr2_list->nbr2 = nbr2;
-  nbr2->nbr2_pointer++;   /* XXX move to olsr_lock_nbr2 () */
-  nbr2_list->nbr2_nbr = nbr;    /* XXX nbr needs refcount protection as well */
+  olsr_lock_nbr2(nbr2);
+
+  nbr2_list->nbr2_nbr = nbr;    /* XXX nbr refcount protection */
 
   /*
    * Start the timer.
@@ -137,12 +138,6 @@ olsr_delete_nbr2_list_entry(struct nbr2_list_entry *nbr2_list)
   nbr2 = nbr2_list->nbr2;
   nbr = nbr2_list->nbr2_nbr;
 
-  /* XXX move to olsr_unlock_nbr2() */
-  if (nbr2->nbr2_pointer < 1) {
-    DEQUEUE_ELEM(nbr2);
-    free(nbr2);
-  }
-
   /*
    * Kill running timers.
    */
@@ -152,6 +147,10 @@ olsr_delete_nbr2_list_entry(struct nbr2_list_entry *nbr2_list)
   /* Remove from neighbor2 reference subtree */
   avl_delete(&nbr->nbr2_list_tree, &nbr2_list->nbr2_list_node);
 
+  /* Remove reference to a two-hop neighbor, unlock */
+  nbr2_list->nbr2 = NULL;
+  olsr_unlock_nbr2(nbr2);
+
   olsr_cookie_free(nbr2_list_mem_cookie, nbr2_list);
 
   /* Set flags to recalculate the MPR set and the routing table */
@@ -235,7 +234,6 @@ olsr_delete_nbr_entry(const union olsr_ip_addr * addr)
   OLSR_DEBUG(LOG_NEIGHTABLE, "Delete 1-hop neighbor: %s\n", olsr_ip_to_string(&buf, addr));
 
   OLSR_FOR_ALL_NBR2_LIST_ENTRIES(nbr, nbr2_list) {
-    nbr2_list->nbr2->nbr2_pointer--;        /* XXX move to olsr_nbr2_unlock() */
     olsr_delete_neighbor_pointer(nbr2_list->nbr2, nbr);
     olsr_delete_nbr2_list_entry(nbr2_list);
   } OLSR_FOR_ALL_NBR2_LIST_ENTRIES_END(nbr, nbr2_list);
@@ -400,8 +398,8 @@ olsr_expire_nbr2_list(void *context)
   nbr = nbr2_list->nbr2_nbr;
   nbr2 = nbr2_list->nbr2;
 
-  nbr2->nbr2_pointer--;   /* XXX move to olsr_unlock_nbr2() */
   olsr_delete_neighbor_pointer(nbr2, nbr);
+  olsr_unlock_nbr2(nbr2);
 
   olsr_delete_nbr2_list_entry(nbr2_list);
 }
index 4fc18d7..abb8252 100644 (file)
@@ -130,7 +130,7 @@ process_message_neighbors(struct nbr_entry *neighbor, const struct lq_hello_mess
           two_hop_neighbor = olsr_malloc(sizeof(*two_hop_neighbor), "Process HELLO");
           two_hop_neighbor->nbr2_nblist.next = &two_hop_neighbor->nbr2_nblist;
           two_hop_neighbor->nbr2_nblist.prev = &two_hop_neighbor->nbr2_nblist;
-          two_hop_neighbor->nbr2_pointer = 0;
+          two_hop_neighbor->nbr2_refcount = 0;
           two_hop_neighbor->nbr2_addr = message_neighbors->addr;
           olsr_insert_two_hop_neighbor_table(two_hop_neighbor);
         }
index 1fff863..56bc163 100644 (file)
@@ -69,6 +69,33 @@ olsr_init_two_hop_table(void)
 }
 
 /**
+ * A Reference to a two-hop neighbor entry has been added.
+ * Bump the refcouunt.
+ */
+void
+olsr_lock_nbr2(struct nbr2_entry *nbr2)
+{
+  nbr2->nbr2_refcount++;
+}
+
+/**
+ * Unlock and free a neighbor 2 entry if the refcount has gone below 1.
+ */
+void
+olsr_unlock_nbr2(struct nbr2_entry *nbr2)
+{
+  if (--nbr2->nbr2_refcount) {
+    return;
+  }
+
+  /*
+   * Nobody is interested in this nbr2 anymore.
+   * Remove all references to it and free.
+   */
+  olsr_delete_two_hop_neighbor_table(nbr2);
+}
+
+/**
  *Remove a one hop neighbor from a two hop neighbors
  *one hop list.
  *
index 2df7cd9..ddbe158 100644 (file)
@@ -66,7 +66,7 @@ struct nbr2_entry {
   struct nbr2_entry *next;
   unsigned int mpr_covered_count;      /* Used in mpr calculation */
   unsigned int processed:1;            /* Used in mpr calculation */
-  unsigned int nbr2_pointer;           /* Neighbor count */
+  unsigned int nbr2_refcount;          /* Reference counter */
   struct timer_entry *nbr2_list_timer;
   struct nbr_list_entry nbr2_nblist;
 } __attribute__ ((packed));;
@@ -91,6 +91,8 @@ struct nbr2_entry {
 extern struct nbr2_entry two_hop_neighbortable[HASHSIZE];
 
 void olsr_init_two_hop_table(void);
+void olsr_lock_nbr2(struct nbr2_entry *);
+void olsr_unlock_nbr2(struct nbr2_entry *);
 void olsr_delete_neighbor_pointer(struct nbr2_entry *, struct nbr_entry *);
 void olsr_delete_two_hop_neighbor_table(struct nbr2_entry *);
 void olsr_insert_two_hop_neighbor_table(struct nbr2_entry *);