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
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/conf/domain_event.c | 74 +++++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_event.h | 21 +++++++++++++
src/libvirt_private.syms | 4 ++
3 files changed, 98 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index c80b891..90153df 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -582,7 +582,8 @@ virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
timeout_cb,
timeout_opaque,
timeout_free)) < 0) {
- goto error;
+ DEBUG0("virEventAddTimeout failed: No addTimeoutImpl defined. "
+ "continuing without events.");
}
return state;
@@ -1051,3 +1052,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) {
+ DEBUG0("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);
+}
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index a465536..ad7e825 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -204,4 +204,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
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5bfbb92..699d602 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -349,8 +349,12 @@ virDomainEventRTCChangeNewFromDom;
virDomainEventRTCChangeNewFromObj;
virDomainEventRebootNewFromDom;
virDomainEventRebootNewFromObj;
+virDomainEventStateDeregister;
+virDomainEventStateDeregisterAny;
+virDomainEventStateFlush;
virDomainEventStateFree;
virDomainEventStateNew;
+virDomainEventStateQueue;
virDomainEventWatchdogNewFromDom;
virDomainEventWatchdogNewFromObj;
--
1.7.3.3