qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 5/5] monitor: remove old entries from event hash


From: marcandre . lureau
Subject: [Qemu-devel] [PATCH v2 5/5] monitor: remove old entries from event hash table
Date: Thu, 17 Sep 2015 18:08:50 +0200

From: Marc-André Lureau <address@hidden>

Do not let the hash table grow without limit, schedule a cleanup for
outdated event.

Signed-off-by: Marc-André Lureau <address@hidden>
---
 monitor.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 53 insertions(+), 5 deletions(-)

diff --git a/monitor.c b/monitor.c
index 90f06ce..a81341f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -541,7 +541,7 @@ static void monitor_qapi_event_handler(void *opaque)
 }
 
 static MonitorQAPIEventPending *
-monitor_qapi_event_pending_new(QAPIEvent event)
+monitor_qapi_event_pending_new(QAPIEvent event, QEMUTimerCB *handler)
 {
     MonitorQAPIEventPending *p;
 
@@ -549,11 +549,52 @@ monitor_qapi_event_pending_new(QAPIEvent event)
     p->event = event;
     p->timer = timer_new(QEMU_CLOCK_REALTIME,
                          SCALE_MS,
-                         monitor_qapi_event_handler,
+                         handler,
                          p);
     return p;
 }
 
+static void monitor_qapi_event_id_remove(MonitorQAPIEventPending *p)
+{
+    MonitorQAPIEventState *s = &monitor_qapi_event_state[p->event];
+    GHashTable *ht = s->delay_data;
+    GHashTableIter iter;
+    gpointer value;
+
+    g_hash_table_iter_init(&iter, ht);
+    while (g_hash_table_iter_next(&iter, NULL, &value)) {
+        if (value == p) {
+            g_hash_table_iter_remove(&iter);
+            return;
+        }
+    }
+}
+
+/*
+ * do not let the hash table grow, if no later pending event
+ * scheduled, remove the old entry after rate timeout.
+ */
+static void monitor_qapi_event_id_schedule_remove(MonitorQAPIEventPending *p)
+{
+    MonitorQAPIEventState *s = &monitor_qapi_event_state[p->event];
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+    int64_t then = now + s->rate;
+
+    timer_mod_ns(p->timer, then);
+}
+
+static void monitor_qapi_event_id_handler(void *opaque)
+{
+    MonitorQAPIEventPending *p = opaque;
+
+    if (p->qdict) {
+        monitor_qapi_event_handler(p);
+        monitor_qapi_event_id_schedule_remove(p);
+    } else {
+        monitor_qapi_event_id_remove(p);
+    }
+}
+
 /*
  * A delay handler that will filter events by the "id" event field.
  * evstate must be an element of the monitor_qapi_event_state array.
@@ -571,11 +612,17 @@ monitor_qapi_event_id_delay(MonitorQAPIEventState 
*evstate, QDict *qdict)
     assert(event >= 0 || event < QAPI_EVENT_MAX);
 
     if (!p) {
-        p = monitor_qapi_event_pending_new(event);
+        p = monitor_qapi_event_pending_new(event,
+                                           monitor_qapi_event_id_handler);
         g_hash_table_insert(ht, g_strdup(id), p);
     }
 
-    return monitor_qapi_event_pending_update(evstate, p, qdict);
+    if (monitor_qapi_event_pending_update(evstate, p, qdict)) {
+        return true;
+    } else {
+        monitor_qapi_event_id_schedule_remove(p);
+        return false;
+    }
 }
 
 /*
@@ -631,7 +678,8 @@ monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
     evstate->rate = rate * SCALE_MS;
 
     evstate->delay = monitor_qapi_event_delay;
-    evstate->delay_data = monitor_qapi_event_pending_new(event);
+    evstate->delay_data =
+        monitor_qapi_event_pending_new(event, monitor_qapi_event_handler);
 }
 
 static void
-- 
2.4.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]