ofproto: Fix potential leak during flow mods.
[sliver-openvswitch.git] / lib / timeval.c
index 8745c50..d2a4380 100644 (file)
@@ -31,6 +31,7 @@
 #include "fatal-signal.h"
 #include "hash.h"
 #include "hmap.h"
+#include "ovs-rcu.h"
 #include "ovs-thread.h"
 #include "signals.h"
 #include "seq.h"
@@ -262,6 +263,7 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED,
 {
     long long int *last_wakeup = last_wakeup_get();
     long long int start;
+    bool quiescent;
     int retval = 0;
 
     time_init();
@@ -273,6 +275,7 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED,
     start = time_msec();
 
     timeout_when = MIN(timeout_when, deadline);
+    quiescent = ovsrcu_is_quiescent();
 
     for (;;) {
         long long int now = time_msec();
@@ -286,6 +289,14 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED,
             time_left = timeout_when - now;
         }
 
+        if (!quiescent) {
+            if (!time_left) {
+                ovsrcu_quiesce();
+            } else {
+                ovsrcu_quiesce_start();
+            }
+        }
+
 #ifndef _WIN32
         retval = poll(pollfds, n_pollfds, time_left);
         if (retval < 0) {
@@ -306,6 +317,10 @@ time_poll(struct pollfd *pollfds, int n_pollfds, HANDLE *handles OVS_UNUSED,
         }
 #endif
 
+        if (!quiescent && time_left) {
+            ovsrcu_quiesce_end();
+        }
+
         if (deadline <= time_msec()) {
 #ifndef _WIN32
             fatal_signal_handler(SIGALRM);
@@ -402,9 +417,17 @@ clock_gettime(clock_t id, struct timespec *ts)
 void
 xgettimeofday(struct timeval *tv)
 {
+#ifndef _WIN32
     if (gettimeofday(tv, NULL) == -1) {
         VLOG_FATAL("gettimeofday failed (%s)", ovs_strerror(errno));
     }
+#else
+    ULARGE_INTEGER current_time = xgetfiletime();
+
+    tv->tv_sec = (current_time.QuadPart - unix_epoch.QuadPart) / 10000000;
+    tv->tv_usec = ((current_time.QuadPart - unix_epoch.QuadPart) %
+                   10000000) / 10;
+#endif
 }
 
 void
@@ -629,7 +652,12 @@ timeval_warp_cb(struct unixctl_conn *conn,
     timespec_add(&monotonic_clock.warp, &monotonic_clock.warp, &ts);
     ovs_mutex_unlock(&monotonic_clock.mutex);
     seq_change(timewarp_seq);
-    poll(NULL, 0, 10); /* give threads (eg. monitor) some chances to run */
+    /* give threads (eg. monitor) some chances to run */
+#ifndef _WIN32
+    poll(NULL, 0, 10);
+#else
+    Sleep(10);
+#endif
     unixctl_command_reply(conn, "warped");
 }