This structure will be used to unify lots of duplicated event handling code
across the state drivers.
v2:
Check for state == NULL in StateFree
Add NONNULL tagging
Use bool for isDispatching
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
cfg.mk | 1 +
src/conf/domain_event.c | 94 ++++++++++++++++++++++++++++++++++++----------
src/conf/domain_event.h | 48 ++++++++++++++++-------
src/libvirt_private.syms | 2 +
4 files changed, 111 insertions(+), 34 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index cb059f5..06b638b 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -103,6 +103,7 @@ useless_free_options = \
--name=virDomainEventCallbackListFree \
--name=virDomainEventFree \
--name=virDomainEventQueueFree \
+ --name=virDomainEventStateFree \
--name=virDomainFSDefFree \
--name=virDomainGraphicsDefFree \
--name=virDomainHostdevDefFree \
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 688bf6c..2771887 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -24,6 +24,7 @@
#include <config.h>
#include "domain_event.h"
+#include "event.h"
#include "logging.h"
#include "datatypes.h"
#include "memory.h"
@@ -505,6 +506,25 @@ void virDomainEventFree(virDomainEventPtr event)
VIR_FREE(event);
}
+/**
+ * virDomainEventQueueFree:
+ * @queue: pointer to the queue
+ *
+ * Free the memory in the queue. We process this like a list here
+ */
+void
+virDomainEventQueueFree(virDomainEventQueuePtr queue)
+{
+ int i;
+ if (!queue)
+ return;
+
+ for (i = 0; i < queue->count ; i++) {
+ virDomainEventFree(queue->events[i]);
+ }
+ VIR_FREE(queue->events);
+ VIR_FREE(queue);
+}
virDomainEventQueuePtr virDomainEventQueueNew(void)
{
@@ -518,6 +538,60 @@ virDomainEventQueuePtr virDomainEventQueueNew(void)
return ret;
}
+/**
+ * virDomainEventStateFree:
+ * @list: virDomainEventStatePtr to free
+ *
+ * Free a virDomainEventStatePtr and its members, and unregister the timer.
+ */
+void
+virDomainEventStateFree(virDomainEventStatePtr state)
+{
+ if (!state)
+ return;
+
+ virDomainEventCallbackListFree(state->callbacks);
+ virDomainEventQueueFree(state->queue);
+
+ if (state->timer != -1)
+ virEventRemoveTimeout(state->timer);
+}
+
+virDomainEventStatePtr
+virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
+ void *timeout_opaque,
+ virFreeCallback timeout_free)
+{
+ virDomainEventStatePtr state = NULL;
+
+ if (VIR_ALLOC(state) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (VIR_ALLOC(state->callbacks) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (!(state->queue = virDomainEventQueueNew())) {
+ goto error;
+ }
+
+ if ((state->timer = virEventAddTimeout(-1,
+ timeout_cb,
+ timeout_opaque,
+ timeout_free)) < 0) {
+ goto error;
+ }
+
+ return state;
+
+error:
+ virDomainEventStateFree(state);
+ return NULL;
+}
+
static virDomainEventPtr virDomainEventNewInternal(int eventID,
int id,
const char *name,
@@ -784,26 +858,6 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr
obj,
/**
- * virDomainEventQueueFree:
- * @queue: pointer to the queue
- *
- * Free the memory in the queue. We process this like a list here
- */
-void
-virDomainEventQueueFree(virDomainEventQueuePtr queue)
-{
- int i;
- if (!queue)
- return;
-
- for (i = 0; i < queue->count ; i++) {
- virDomainEventFree(queue->events[i]);
- }
- VIR_FREE(queue->events);
- VIR_FREE(queue);
-}
-
-/**
* virDomainEventQueuePop:
* @evtQueue: the queue of events
*
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index c03a159..2ac3ecc 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -25,6 +25,7 @@
#ifndef __DOMAIN_EVENT_H__
# define __DOMAIN_EVENT_H__
+# include "event.h"
# include "domain_conf.h"
typedef struct _virDomainEventCallback virDomainEventCallback;
@@ -38,6 +39,33 @@ struct _virDomainEventCallbackList {
typedef struct _virDomainEventCallbackList virDomainEventCallbackList;
typedef virDomainEventCallbackList *virDomainEventCallbackListPtr;
+/**
+ * Dispatching domain events that come in while
+ * in a call / response rpc
+ */
+typedef struct _virDomainEvent virDomainEvent;
+typedef virDomainEvent *virDomainEventPtr;
+
+struct _virDomainEventQueue {
+ unsigned int count;
+ virDomainEventPtr *events;
+};
+typedef struct _virDomainEventQueue virDomainEventQueue;
+typedef virDomainEventQueue *virDomainEventQueuePtr;
+
+struct _virDomainEventState {
+ /* The list of domain event callbacks */
+ virDomainEventCallbackListPtr callbacks;
+ /* The queue of domain events */
+ virDomainEventQueuePtr queue;
+ /* Timer for flushing events queue */
+ int timer;
+ /* Flag if we're in process of dispatching */
+ bool isDispatching;
+};
+typedef struct _virDomainEventState virDomainEventState;
+typedef virDomainEventState *virDomainEventStatePtr;
+
void virDomainEventCallbackListFree(virDomainEventCallbackListPtr list);
int virDomainEventCallbackListAdd(virConnectPtr conn,
@@ -91,20 +119,6 @@ int virDomainEventCallbackListEventID(virConnectPtr conn,
int callbackID)
ATTRIBUTE_NONNULL(1);
-/**
- * Dispatching domain events that come in while
- * in a call / response rpc
- */
-typedef struct _virDomainEvent virDomainEvent;
-typedef virDomainEvent *virDomainEventPtr;
-
-struct _virDomainEventQueue {
- unsigned int count;
- virDomainEventPtr *events;
-};
-typedef struct _virDomainEventQueue virDomainEventQueue;
-typedef virDomainEventQueue *virDomainEventQueuePtr;
-
virDomainEventQueuePtr virDomainEventQueueNew(void);
virDomainEventPtr virDomainEventNew(int id, const char *name, const unsigned char *uuid,
int type, int detail);
@@ -164,6 +178,12 @@ virDomainEventQueuePop(virDomainEventQueuePtr evtQueue);
void virDomainEventFree(virDomainEventPtr event);
void virDomainEventQueueFree(virDomainEventQueuePtr queue);
+void virDomainEventStateFree(virDomainEventStatePtr state);
+virDomainEventStatePtr
+virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
+ void *timeout_opaque,
+ virFreeCallback timeout_free)
+ ATTRIBUTE_NONNULL(1);
typedef void (*virDomainEventDispatchFunc)(virConnectPtr conn,
virDomainEventPtr event,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7e5b1d7..d4ad0c8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -389,6 +389,8 @@ virDomainEventRTCChangeNewFromObj;
virDomainEventRebootNew;
virDomainEventRebootNewFromDom;
virDomainEventRebootNewFromObj;
+virDomainEventStateFree;
+virDomainEventStateNew;
virDomainEventWatchdogNewFromDom;
virDomainEventWatchdogNewFromObj;
--
1.7.4.4