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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list