]> xenbits.xensource.com Git - libvirt.git/commitdiff
domain_event: Add common domain event queue/flush helpers
authorCole Robinson <crobinso@redhat.com>
Wed, 5 Jan 2011 22:51:45 +0000 (17:51 -0500)
committerCole Robinson <crobinso@redhat.com>
Fri, 13 May 2011 14:48:32 +0000 (10:48 -0400)
The same code for queueing, flushing, and deregistering events exists
in multiple drivers, which will soon use these common functions.

v2:
    Adjust libvirt_private.syms
    isDispatching bool fixes
    NONNULL tagging

v3:
    Add requireTimer parameter to virDomainEventStateNew

src/conf/domain_event.c
src/conf/domain_event.h
src/libvirt_private.syms

index 27718876933b66fe83a4baf8ee60ef473058ed73..b85765ebbaba88c280fd0deffdf7a393ce07a813 100644 (file)
@@ -557,10 +557,21 @@ virDomainEventStateFree(virDomainEventStatePtr state)
         virEventRemoveTimeout(state->timer);
 }
 
+/**
+ * virDomainEventStateNew:
+ * @timeout_cb: virEventTimeoutCallback to call when timer expires
+ * @timeout_opaque: Data for timeout_cb
+ * @timeout_free: Optional virFreeCallback for freeing timeout_opaque
+ * @requireTimer: If true, return an error if registering the timer fails.
+ *                This is fatal for drivers that sit behind the daemon
+ *                (qemu, lxc), since there should always be a event impl
+ *                registered.
+ */
 virDomainEventStatePtr
 virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
                        void *timeout_opaque,
-                       virFreeCallback timeout_free)
+                       virFreeCallback timeout_free,
+                       bool requireTimer)
 {
     virDomainEventStatePtr state = NULL;
 
@@ -582,7 +593,14 @@ virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
                                            timeout_cb,
                                            timeout_opaque,
                                            timeout_free)) < 0) {
-        goto error;
+        if (requireTimer == false) {
+            VIR_DEBUG("virEventAddTimeout failed: No addTimeoutImpl defined. "
+                      "continuing without events.");
+        } else {
+            eventReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("could not initialize domain event timer"));
+            goto error;
+        }
     }
 
     return state;
@@ -1059,3 +1077,74 @@ void virDomainEventQueueDispatch(virDomainEventQueuePtr queue,
     VIR_FREE(queue->events);
     queue->count = 0;
 }
+
+void
+virDomainEventStateQueue(virDomainEventStatePtr state,
+                         virDomainEventPtr event)
+{
+    if (state->timer < 0) {
+        virDomainEventFree(event);
+        return;
+    }
+
+    if (virDomainEventQueuePush(state->queue, event) < 0) {
+        VIR_DEBUG("Error adding event to queue");
+        virDomainEventFree(event);
+    }
+
+    if (state->queue->count == 1)
+        virEventUpdateTimeout(state->timer, 0);
+}
+
+void
+virDomainEventStateFlush(virDomainEventStatePtr state,
+                         virDomainEventDispatchFunc dispatchFunc,
+                         void *opaque)
+{
+    virDomainEventQueue tempQueue;
+
+    state->isDispatching = true;
+
+    /* Copy the queue, so we're reentrant safe when dispatchFunc drops the
+     * driver lock */
+    tempQueue.count = state->queue->count;
+    tempQueue.events = state->queue->events;
+    state->queue->count = 0;
+    state->queue->events = NULL;
+
+    virEventUpdateTimeout(state->timer, -1);
+    virDomainEventQueueDispatch(&tempQueue,
+                                state->callbacks,
+                                dispatchFunc,
+                                opaque);
+
+    /* Purge any deleted callbacks */
+    virDomainEventCallbackListPurgeMarked(state->callbacks);
+
+    state->isDispatching = false;
+}
+
+int
+virDomainEventStateDeregister(virConnectPtr conn,
+                              virDomainEventStatePtr state,
+                              virConnectDomainEventCallback callback)
+{
+    if (state->isDispatching)
+        return virDomainEventCallbackListMarkDelete(conn,
+                                                    state->callbacks, callback);
+    else
+        return virDomainEventCallbackListRemove(conn, state->callbacks, callback);
+}
+
+int
+virDomainEventStateDeregisterAny(virConnectPtr conn,
+                                 virDomainEventStatePtr state,
+                                 int callbackID)
+{
+    if (state->isDispatching)
+        return virDomainEventCallbackListMarkDeleteID(conn,
+                                                      state->callbacks, callbackID);
+    else
+        return virDomainEventCallbackListRemoveID(conn,
+                                                  state->callbacks, callbackID);
+}
index 2ac3ecc98c0e9164db41107ac5547dd13e72dd3e..efc05f9359466dd0181b4d5ea1b8ae08a3fe07e8 100644 (file)
@@ -182,7 +182,8 @@ void virDomainEventStateFree(virDomainEventStatePtr state);
 virDomainEventStatePtr
 virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
                        void *timeout_opaque,
-                       virFreeCallback timeout_free)
+                       virFreeCallback timeout_free,
+                       bool requireTimer)
     ATTRIBUTE_NONNULL(1);
 
 typedef void (*virDomainEventDispatchFunc)(virConnectPtr conn,
@@ -205,4 +206,25 @@ void virDomainEventQueueDispatch(virDomainEventQueuePtr queue,
                                  virDomainEventDispatchFunc dispatch,
                                  void *opaque);
 
+
+void
+virDomainEventStateQueue(virDomainEventStatePtr state,
+                         virDomainEventPtr event)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+void
+virDomainEventStateFlush(virDomainEventStatePtr state,
+                         virDomainEventDispatchFunc dispatchFunc,
+                         void *opaque)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int
+virDomainEventStateDeregister(virConnectPtr conn,
+                              virDomainEventStatePtr state,
+                              virConnectDomainEventCallback callback)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+int
+virDomainEventStateDeregisterAny(virConnectPtr conn,
+                                 virDomainEventStatePtr state,
+                                 int callbackID)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
 #endif
index d4ad0c80db7404858256e846c2fd3bfc7a35d1b6..c98efdcfaf965b684a51fa7e9f8565aa716adc26 100644 (file)
@@ -389,8 +389,12 @@ virDomainEventRTCChangeNewFromObj;
 virDomainEventRebootNew;
 virDomainEventRebootNewFromDom;
 virDomainEventRebootNewFromObj;
+virDomainEventStateDeregister;
+virDomainEventStateDeregisterAny;
+virDomainEventStateFlush;
 virDomainEventStateFree;
 virDomainEventStateNew;
+virDomainEventStateQueue;
 virDomainEventWatchdogNewFromDom;
 virDomainEventWatchdogNewFromObj;