ofproto-dpif-monitor: Remove monitor_init().
[sliver-openvswitch.git] / ofproto / ofproto-dpif-monitor.c
index af66387..33115f3 100644 (file)
@@ -53,7 +53,7 @@ struct mport {
 };
 
 /* hmap that contains "struct mport"s. */
-static struct hmap monitor_hmap;
+static struct hmap monitor_hmap = HMAP_INITIALIZER(&monitor_hmap);
 
 /* heap for ordering mport based on bfd/cfm wakeup time. */
 static struct heap monitor_heap;
@@ -66,7 +66,6 @@ static bool monitor_running;
 static struct latch monitor_exit_latch;
 static struct ovs_rwlock monitor_rwlock = OVS_RWLOCK_INITIALIZER;
 
-static void monitor_init(void);
 static void *monitor_main(void *);
 static void monitor_run(void);
 
@@ -155,18 +154,6 @@ mport_update(struct mport *mport, struct bfd *bfd, struct cfm *cfm,
 }
 \f
 
-/* Initializes the global variables.  This will only run once. */
-static void
-monitor_init(void)
-{
-    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
-
-    if (ovsthread_once_start(&once)) {
-        hmap_init(&monitor_hmap);
-        ovsthread_once_done(&once);
-    }
-}
-
 /* The 'main' function for the monitor thread. */
 static void *
 monitor_main(void * args OVS_UNUSED)
@@ -225,8 +212,9 @@ monitor_run(void)
             bfd_wait(mport->bfd);
         }
         /* Computes the next wakeup time for this mport. */
-        next_wake_time = MIN(bfd_wake_time(mport->bfd), cfm_wake_time(mport->cfm));
-        heap_change(&monitor_heap, heap_max(&monitor_heap),
+        next_wake_time = MIN(bfd_wake_time(mport->bfd),
+                             cfm_wake_time(mport->cfm));
+        heap_change(&monitor_heap, &mport->heap_node,
                     MSEC_TO_PRIO(next_wake_time));
     }
 
@@ -252,7 +240,6 @@ ofproto_dpif_monitor_port_update(const struct ofport_dpif *ofport,
                                  struct bfd *bfd, struct cfm *cfm,
                                  uint8_t hw_addr[ETH_ADDR_LEN])
 {
-    monitor_init();
     ovs_rwlock_wrlock(&monitor_rwlock);
     if (!cfm && !bfd) {
         mport_unregister(ofport);
@@ -275,3 +262,26 @@ ofproto_dpif_monitor_port_update(const struct ofport_dpif *ofport,
         monitor_running = false;
     }
 }
+
+/* Moves the mport on top of the heap.  This is necessary when
+ * for example, bfd POLL is received and the mport should
+ * immediately send FINAL back. */
+void
+ofproto_dpif_monitor_port_send_soon_safe(const struct ofport_dpif *ofport)
+{
+    ovs_rwlock_wrlock(&monitor_rwlock);
+    ofproto_dpif_monitor_port_send_soon(ofport);
+    ovs_rwlock_unlock(&monitor_rwlock);
+}
+
+void
+ofproto_dpif_monitor_port_send_soon(const struct ofport_dpif *ofport)
+    OVS_REQ_WRLOCK(monitor_rwlock)
+{
+    struct mport *mport;
+
+    mport = mport_find(ofport);
+    if (mport) {
+        heap_change(&monitor_heap, &mport->heap_node, LLONG_MAX);
+    }
+}