[libvirt] [PATCH 1/2] virDomainEvent refactoring to separate generic things from domain ones

Cédric Bosdonnat cbosdonnat at suse.com
Tue Nov 19 15:43:13 UTC 2013


The idea behind this commit is to make use of the Domain event
mechanism for other events like network ones. This introduces some
renaming from virDomainEvent* to virOjbectEvent*.
---
 .gitignore                      |    1 +
 include/libvirt/libvirt.h.in    |    8 +
 src/Makefile.am                 |    6 +
 src/conf/domain_event.c         | 1431 +++++++--------------------------------
 src/conf/domain_event.h         |  134 ++--
 src/conf/object_event.c         |  918 +++++++++++++++++++++++++
 src/conf/object_event.h         |   93 +++
 src/conf/object_event_private.h |  160 +++++
 src/libvirt_private.syms        |   15 +-
 src/libxl/libxl_conf.h          |    2 +-
 src/libxl/libxl_driver.c        |   28 +-
 src/lxc/lxc_conf.h              |    2 +-
 src/lxc/lxc_driver.c            |   38 +-
 src/lxc/lxc_process.c           |   12 +-
 src/parallels/parallels_utils.h |    2 +-
 src/qemu/qemu_conf.h            |    2 +-
 src/qemu/qemu_domain.c          |    6 +-
 src/qemu/qemu_domain.h          |    2 +-
 src/qemu/qemu_driver.c          |   50 +-
 src/qemu/qemu_hotplug.c         |   10 +-
 src/qemu/qemu_migration.c       |   12 +-
 src/qemu/qemu_process.c         |   48 +-
 src/remote/remote_driver.c      |   50 +-
 src/test/test_driver.c          |   50 +-
 src/uml/uml_conf.h              |    2 +-
 src/uml/uml_driver.c            |   26 +-
 src/vbox/vbox_tmpl.c            |   20 +-
 src/xen/xen_driver.c            |   10 +-
 src/xen/xen_driver.h            |    4 +-
 src/xen/xen_inotify.c           |    8 +-
 src/xen/xs_internal.c           |    4 +-
 tests/qemuhotplugtest.c         |    2 +-
 32 files changed, 1687 insertions(+), 1469 deletions(-)
 create mode 100644 src/conf/object_event.c
 create mode 100644 src/conf/object_event.h
 create mode 100644 src/conf/object_event_private.h

diff --git a/.gitignore b/.gitignore
index 6b024e7..05be8a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -170,6 +170,7 @@
 /tests/networkxml2argvtest
 /tests/nodeinfotest
 /tests/nwfilterxml2xmltest
+/tests/objecteventtest
 /tests/object-locking
 /tests/object-locking-files.txt
 /tests/object-locking.cm[ix]
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 146a59b..b13118d 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -4959,6 +4959,14 @@ typedef enum {
 } virDomainEventID;
 
 
+/** Event IDs are computed in the following way:
+    virEventNamespaceID << 8 + vir*EventId
+  */
+typedef enum {
+    VIR_EVENT_NAMESPACE_DOMAIN = 0, /* 0 to keep value of virDomainEventId unchanged */
+} virEventNamespaceID;
+
+
 /* Use VIR_DOMAIN_EVENT_CALLBACK() to cast the 'cb' parameter  */
 int virConnectDomainEventRegisterAny(virConnectPtr conn,
                                      virDomainPtr dom, /* Optional, to filter */
diff --git a/src/Makefile.am b/src/Makefile.am
index ad39b74..8507b55 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -241,6 +241,10 @@ DOMAIN_CONF_SOURCES =						\
 		conf/domain_nwfilter.c conf/domain_nwfilter.h	\
 		conf/snapshot_conf.c conf/snapshot_conf.h
 
+OBJECT_EVENT_SOURCES =						\
+		conf/object_event.h conf/object_event.c \
+		conf/objec_event_private.h
+
 DOMAIN_EVENT_SOURCES =						\
 		conf/domain_event.c conf/domain_event.h
 
@@ -292,6 +296,7 @@ DEVICE_CONF_SOURCES =                                           \
 CONF_SOURCES =							\
 		$(NETDEV_CONF_SOURCES)				\
 		$(DOMAIN_CONF_SOURCES)				\
+		$(OBJECT_EVENT_SOURCES)				\
 		$(DOMAIN_EVENT_SOURCES)				\
 		$(NETWORK_CONF_SOURCES)				\
 		$(NWFILTER_CONF_SOURCES)			\
@@ -2010,6 +2015,7 @@ libvirt_setuid_rpc_client_la_SOURCES = 		\
 		util/virutil.c			\
 		util/viruuid.c			\
 		conf/domain_event.c		\
+		conf/object_event.c		\
 		rpc/virnetsocket.c		\
 		rpc/virnetsocket.h		\
 		rpc/virnetmessage.h		\
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 19e3920..4a6038a 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -23,6 +23,8 @@
 
 #include <config.h>
 
+#include "object_event.h"
+#include "object_event_private.h"
 #include "domain_event.h"
 #include "virlog.h"
 #include "datatypes.h"
@@ -32,163 +34,93 @@
 
 #define VIR_FROM_THIS VIR_FROM_NONE
 
-struct _virDomainMeta {
-    int id;
-    char *name;
-    unsigned char uuid[VIR_UUID_BUFLEN];
-};
-typedef struct _virDomainMeta virDomainMeta;
-typedef virDomainMeta *virDomainMetaPtr;
-
-struct _virDomainEventCallbackList {
-    unsigned int nextID;
-    unsigned int count;
-    virDomainEventCallbackPtr *callbacks;
-};
-
-struct _virDomainEventQueue {
-    unsigned int count;
-    virDomainEventPtr *events;
-};
-
-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;
-    virMutex lock;
-};
-
-struct _virDomainEventCallback {
-    int callbackID;
-    int eventID;
-    virConnectPtr conn;
-    virDomainMetaPtr dom;
-    virConnectDomainEventGenericCallback cb;
-    void *opaque;
-    virFreeCallback freecb;
-    int deleted;
-};
-
-struct _virDomainEvent {
-    int eventID;
-
-    virDomainMeta dom;
-
-    union {
-        struct {
-            int type;
-            int detail;
-        } lifecycle;
-        struct {
-            long long offset;
-        } rtcChange;
-        struct {
-            int action;
-        } watchdog;
-        struct {
-            char *srcPath;
-            char *devAlias;
-            int action;
-            char *reason;
-        } ioError;
-        struct {
-            int phase;
-            virDomainEventGraphicsAddressPtr local;
-            virDomainEventGraphicsAddressPtr remote;
-            char *authScheme;
-            virDomainEventGraphicsSubjectPtr subject;
-        } graphics;
-        struct {
-            char *path;
-            int type;
-            int status;
-        } blockJob;
-        struct {
-            char *oldSrcPath;
-            char *newSrcPath;
-            char *devAlias;
-            int reason;
-        } diskChange;
-        struct {
-            char *devAlias;
-            int reason;
-        } trayChange;
-        struct {
-            /* In unit of 1024 bytes */
-            unsigned long long actual;
-        } balloonChange;
-        struct {
-            char *devAlias;
-        } deviceRemoved;
-    } data;
-};
 
 /**
- * virDomainEventCallbackListFree:
- * @list: event callback list head
+ * virDomainEventCallbackListAdd:
+ * @conn: pointer to the connection
+ * @cbList: the list
+ * @callback: the callback to add
+ * @opaque: opaque data tio pass to callback
  *
- * Free the memory in the domain event callback list
+ * Internal function to add a callback from a virObjectEventCallbackListPtr
  */
-static void
-virDomainEventCallbackListFree(virDomainEventCallbackListPtr list)
+static int
+virDomainEventCallbackListAdd(virConnectPtr conn,
+                              virObjectEventCallbackListPtr cbList,
+                              virConnectDomainEventCallback callback,
+                              void *opaque,
+                              virFreeCallback freecb)
 {
-    size_t i;
-    if (!list)
-        return;
-
-    for (i=0; i<list->count; i++) {
-        virFreeCallback freecb = list->callbacks[i]->freecb;
-        if (freecb)
-            (*freecb)(list->callbacks[i]->opaque);
-        VIR_FREE(list->callbacks[i]);
-    }
-    VIR_FREE(list->callbacks);
-    VIR_FREE(list);
+    return virObjectEventCallbackListAddID(conn, cbList, NULL, NULL, 0,
+                                           VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+                                           VIR_OBJECT_EVENT_CALLBACK(callback),
+                                           opaque, freecb, NULL);
 }
 
 
 /**
- * virDomainEventCallbackListRemove:
- * @conn: pointer to the connection
- * @cbList: the list
- * @callback: the callback to remove
+ * virDomainEventStateRegister:
+ * @conn: connection to associate with callback
+ * @state: object event state
+ * @callback: function to remove from event
+ * @opaque: data blob to pass to callback
+ * @freecb: callback to free @opaque
  *
- * Internal function to remove a callback from a virDomainEventCallbackListPtr
+ * Register the function @callback with connection @conn,
+ * from @state, for lifecycle events.
+ *
+ * Returns: the number of lifecycle callbacks now registered, or -1 on error
  */
+int
+virDomainEventStateRegister(virConnectPtr conn,
+                            virObjectEventStatePtr state,
+                            virConnectDomainEventCallback callback,
+                            void *opaque,
+                            virFreeCallback freecb)
+{
+    int ret = -1;
+
+    virObjectEventStateLock(state);
+
+    if ((state->callbacks->count == 0) &&
+        (state->timer == -1) &&
+        (state->timer = virEventAddTimeout(-1,
+                                           virObjectEventTimer,
+                                           state,
+                                           NULL)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("could not initialize domain event timer"));
+        goto cleanup;
+    }
+
+    ret = virDomainEventCallbackListAdd(conn, state->callbacks,
+                                        callback, opaque, freecb);
+
+    if (ret == -1 &&
+        state->callbacks->count == 0 &&
+        state->timer != -1) {
+        virEventRemoveTimeout(state->timer);
+        state->timer = -1;
+    }
+
+cleanup:
+    virObjectEventStateUnlock(state);
+    return ret;
+}
+
+
 static int
-virDomainEventCallbackListRemove(virConnectPtr conn,
-                                 virDomainEventCallbackListPtr cbList,
-                                 virConnectDomainEventCallback callback)
+virDomainEventCallbackListMarkDelete(virConnectPtr conn,
+                                     virObjectEventCallbackListPtr cbList,
+                                     virConnectDomainEventCallback callback)
 {
     int ret = 0;
     size_t i;
     for (i = 0; i < cbList->count; i++) {
-        if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
+        if (cbList->callbacks[i]->cb == VIR_OBJECT_EVENT_CALLBACK(callback) &&
             cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
             cbList->callbacks[i]->conn == conn) {
-            virFreeCallback freecb = cbList->callbacks[i]->freecb;
-            if (freecb)
-                (*freecb)(cbList->callbacks[i]->opaque);
-            virObjectUnref(cbList->callbacks[i]->conn);
-            VIR_FREE(cbList->callbacks[i]);
-
-            if (i < (cbList->count - 1))
-                memmove(cbList->callbacks + i,
-                        cbList->callbacks + i + 1,
-                        sizeof(*(cbList->callbacks)) *
-                                (cbList->count - (i + 1)));
-
-            if (VIR_REALLOC_N(cbList->callbacks,
-                              cbList->count - 1) < 0) {
-                ; /* Failure to reduce memory allocation isn't fatal */
-            }
-            cbList->count--;
-
+            cbList->callbacks[i]->deleted = 1;
             for (i = 0; i < cbList->count; i++) {
                 if (!cbList->callbacks[i]->deleted)
                     ret++;
@@ -198,28 +130,29 @@ virDomainEventCallbackListRemove(virConnectPtr conn,
     }
 
     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                   _("could not find event callback for removal"));
+                   _("could not find event callback for deletion"));
     return -1;
 }
 
 
 /**
- * virDomainEventCallbackListRemoveID:
+ * virDomainEventCallbackListRemove:
  * @conn: pointer to the connection
  * @cbList: the list
  * @callback: the callback to remove
  *
- * Internal function to remove a callback from a virDomainEventCallbackListPtr
+ * Internal function to remove a callback from a virObjectEventCallbackListPtr
  */
 static int
-virDomainEventCallbackListRemoveID(virConnectPtr conn,
-                                   virDomainEventCallbackListPtr cbList,
-                                   int callbackID)
+virDomainEventCallbackListRemove(virConnectPtr conn,
+                                 virObjectEventCallbackListPtr cbList,
+                                 virConnectDomainEventCallback callback)
 {
     int ret = 0;
     size_t i;
     for (i = 0; i < cbList->count; i++) {
-        if (cbList->callbacks[i]->callbackID == callbackID &&
+        if (cbList->callbacks[i]->cb == VIR_OBJECT_EVENT_CALLBACK(callback) &&
+            cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
             cbList->callbacks[i]->conn == conn) {
             virFreeCallback freecb = cbList->callbacks[i]->freecb;
             if (freecb)
@@ -253,543 +186,159 @@ virDomainEventCallbackListRemoveID(virConnectPtr conn,
 }
 
 
-static int
-virDomainEventCallbackListMarkDelete(virConnectPtr conn,
-                                     virDomainEventCallbackListPtr cbList,
-                                     virConnectDomainEventCallback callback)
-{
-    int ret = 0;
-    size_t i;
-    for (i = 0; i < cbList->count; i++) {
-        if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
-            cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
-            cbList->callbacks[i]->conn == conn) {
-            cbList->callbacks[i]->deleted = 1;
-            for (i = 0; i < cbList->count; i++) {
-                if (!cbList->callbacks[i]->deleted)
-                    ret++;
-            }
-            return ret;
-        }
-    }
-
-    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                   _("could not find event callback for deletion"));
-    return -1;
-}
-
-
-static int
-virDomainEventCallbackListMarkDeleteID(virConnectPtr conn,
-                                       virDomainEventCallbackListPtr cbList,
-                                       int callbackID)
-{
-    int ret = 0;
-    size_t i;
-    for (i = 0; i < cbList->count; i++) {
-        if (cbList->callbacks[i]->callbackID == callbackID &&
-            cbList->callbacks[i]->conn == conn) {
-            cbList->callbacks[i]->deleted = 1;
-            for (i = 0; i < cbList->count; i++) {
-                if (!cbList->callbacks[i]->deleted)
-                    ret++;
-            }
-            return ret;
-        }
-    }
-
-    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                   _("could not find event callback for deletion"));
-    return -1;
-}
-
-
-static int
-virDomainEventCallbackListPurgeMarked(virDomainEventCallbackListPtr cbList)
-{
-    int old_count = cbList->count;
-    int n;
-    for (n = 0; n < cbList->count; n++) {
-        if (cbList->callbacks[n]->deleted) {
-            virFreeCallback freecb = cbList->callbacks[n]->freecb;
-            if (freecb)
-                (*freecb)(cbList->callbacks[n]->opaque);
-            virObjectUnref(cbList->callbacks[n]->conn);
-            VIR_FREE(cbList->callbacks[n]);
-
-            if (n < (cbList->count - 1))
-                memmove(cbList->callbacks + n,
-                        cbList->callbacks + n + 1,
-                        sizeof(*(cbList->callbacks)) *
-                                (cbList->count - (n + 1)));
-            cbList->count--;
-            n--;
-        }
-    }
-    if (cbList->count < old_count &&
-        VIR_REALLOC_N(cbList->callbacks, cbList->count) < 0) {
-        ; /* Failure to reduce memory allocation isn't fatal */
-    }
-    return 0;
-}
-
-
-/**
- * virDomainEventCallbackListAddID:
- * @conn: pointer to the connection
- * @cbList: the list
- * @eventID: the event ID
- * @callback: the callback to add
- * @opaque: opaque data tio pass to callback
- * @callbackID: filled with callback ID
- *
- * Internal function to add a callback from a virDomainEventCallbackListPtr
- */
-static int
-virDomainEventCallbackListAddID(virConnectPtr conn,
-                                virDomainEventCallbackListPtr cbList,
-                                virDomainPtr dom,
-                                int eventID,
-                                virConnectDomainEventGenericCallback callback,
-                                void *opaque,
-                                virFreeCallback freecb,
-                                int *callbackID)
-{
-    virDomainEventCallbackPtr event;
-    size_t i;
-    int ret = 0;
-
-    /* Check incoming */
-    if (!cbList) {
-        return -1;
-    }
-
-    /* check if we already have this callback on our list */
-    for (i = 0; i < cbList->count; i++) {
-        if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) &&
-            cbList->callbacks[i]->eventID == eventID &&
-            cbList->callbacks[i]->conn == conn &&
-            ((dom && cbList->callbacks[i]->dom &&
-              memcmp(cbList->callbacks[i]->dom->uuid,
-                     dom->uuid, VIR_UUID_BUFLEN) == 0) ||
-             (!dom && !cbList->callbacks[i]->dom))) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("event callback already tracked"));
-            return -1;
-        }
-    }
-    /* Allocate new event */
-    if (VIR_ALLOC(event) < 0)
-        goto error;
-    event->conn = conn;
-    event->cb = callback;
-    event->eventID = eventID;
-    event->opaque = opaque;
-    event->freecb = freecb;
-
-    if (dom) {
-        if (VIR_ALLOC(event->dom) < 0)
-            goto error;
-        if (VIR_STRDUP(event->dom->name, dom->name) < 0)
-            goto error;
-        memcpy(event->dom->uuid, dom->uuid, VIR_UUID_BUFLEN);
-        event->dom->id = dom->id;
-    }
-
-    /* Make space on list */
-    if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0)
-        goto error;
-
-    virObjectRef(event->conn);
-
-    cbList->callbacks[cbList->count] = event;
-    cbList->count++;
-
-    event->callbackID = cbList->nextID++;
-
-    for (i = 0; i < cbList->count; i++) {
-        if (cbList->callbacks[i]->eventID == eventID &&
-            cbList->callbacks[i]->conn == conn &&
-            !cbList->callbacks[i]->deleted)
-            ret++;
-    }
-
-    if (callbackID)
-        *callbackID = event->callbackID;
-
-    return ret;
-
-error:
-    if (event) {
-        if (event->dom)
-            VIR_FREE(event->dom->name);
-        VIR_FREE(event->dom);
-    }
-    VIR_FREE(event);
-    return -1;
-}
-
-
 /**
- * virDomainEventCallbackListAdd:
- * @conn: pointer to the connection
- * @cbList: the list
- * @callback: the callback to add
- * @opaque: opaque data tio pass to callback
- *
- * Internal function to add a callback from a virDomainEventCallbackListPtr
- */
-static int
-virDomainEventCallbackListAdd(virConnectPtr conn,
-                              virDomainEventCallbackListPtr cbList,
-                              virConnectDomainEventCallback callback,
-                              void *opaque,
-                              virFreeCallback freecb)
-{
-    return virDomainEventCallbackListAddID(conn, cbList, NULL,
-                                           VIR_DOMAIN_EVENT_ID_LIFECYCLE,
-                                           VIR_DOMAIN_EVENT_CALLBACK(callback),
-                                           opaque, freecb, NULL);
-}
-
-
-
-static int
-virDomainEventCallbackListEventID(virConnectPtr conn,
-                                  virDomainEventCallbackListPtr cbList,
-                                  int callbackID)
-{
-    size_t i;
-
-    for (i = 0; i < cbList->count; i++) {
-        if (cbList->callbacks[i]->deleted)
-            continue;
-
-        if (cbList->callbacks[i]->callbackID == callbackID &&
-            cbList->callbacks[i]->conn == conn)
-            return cbList->callbacks[i]->eventID;
-    }
-
-    return -1;
-}
-
-
-void virDomainEventFree(virDomainEventPtr event)
-{
-    if (!event)
-        return;
-
-    switch (event->eventID) {
-    case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
-    case VIR_DOMAIN_EVENT_ID_IO_ERROR:
-        VIR_FREE(event->data.ioError.srcPath);
-        VIR_FREE(event->data.ioError.devAlias);
-        VIR_FREE(event->data.ioError.reason);
-        break;
-
-    case VIR_DOMAIN_EVENT_ID_GRAPHICS:
-        if (event->data.graphics.local) {
-            VIR_FREE(event->data.graphics.local->node);
-            VIR_FREE(event->data.graphics.local->service);
-            VIR_FREE(event->data.graphics.local);
-        }
-        if (event->data.graphics.remote) {
-            VIR_FREE(event->data.graphics.remote->node);
-            VIR_FREE(event->data.graphics.remote->service);
-            VIR_FREE(event->data.graphics.remote);
-        }
-        VIR_FREE(event->data.graphics.authScheme);
-        if (event->data.graphics.subject) {
-            size_t i;
-            for (i = 0; i < event->data.graphics.subject->nidentity; i++) {
-                VIR_FREE(event->data.graphics.subject->identities[i].type);
-                VIR_FREE(event->data.graphics.subject->identities[i].name);
-            }
-            VIR_FREE(event->data.graphics.subject);
-        }
-        break;
-
-    case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
-        VIR_FREE(event->data.blockJob.path);
-        break;
-
-    case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
-        VIR_FREE(event->data.diskChange.oldSrcPath);
-        VIR_FREE(event->data.diskChange.newSrcPath);
-        VIR_FREE(event->data.diskChange.devAlias);
-        break;
-    case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
-        VIR_FREE(event->data.trayChange.devAlias);
-        break;
-    case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
-        VIR_FREE(event->data.deviceRemoved.devAlias);
-        break;
-    }
-
-    VIR_FREE(event->dom.name);
-    VIR_FREE(event);
-}
-
-/**
- * virDomainEventQueueClear:
- * @queue: pointer to the queue
- *
- * Removes all elements from the queue
- */
-static void
-virDomainEventQueueClear(virDomainEventQueuePtr queue)
-{
-    size_t i;
-    if (!queue)
-        return;
-
-    for (i = 0; i < queue->count; i++) {
-        virDomainEventFree(queue->events[i]);
-    }
-    VIR_FREE(queue->events);
-    queue->count = 0;
-}
-
-/**
- * virDomainEventQueueFree:
- * @queue: pointer to the queue
- *
- * Free the memory in the queue. We process this like a list here
- */
-static void
-virDomainEventQueueFree(virDomainEventQueuePtr queue)
-{
-    if (!queue)
-        return;
-
-    virDomainEventQueueClear(queue);
-    VIR_FREE(queue);
-}
-
-static virDomainEventQueuePtr
-virDomainEventQueueNew(void)
-{
-    virDomainEventQueuePtr ret;
-
-    ignore_value(VIR_ALLOC(ret));
-    return ret;
-}
-
-static void
-virDomainEventStateLock(virDomainEventStatePtr state)
-{
-    virMutexLock(&state->lock);
-}
-
-static void
-virDomainEventStateUnlock(virDomainEventStatePtr state)
-{
-    virMutexUnlock(&state->lock);
-}
-
-/**
- * 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);
-
-    virMutexDestroy(&state->lock);
-    VIR_FREE(state);
-}
-
-
-static void virDomainEventStateFlush(virDomainEventStatePtr state);
-
-static void
-virDomainEventTimer(int timer ATTRIBUTE_UNUSED, void *opaque)
-{
-    virDomainEventStatePtr state = opaque;
-
-    virDomainEventStateFlush(state);
-}
-
-/**
- * virDomainEventStateNew:
- */
-virDomainEventStatePtr
-virDomainEventStateNew(void)
-{
-    virDomainEventStatePtr state = NULL;
-
-    if (VIR_ALLOC(state) < 0)
-        goto error;
-
-    if (virMutexInit(&state->lock) < 0) {
-        virReportSystemError(errno, "%s",
-                             _("unable to initialize state mutex"));
-        VIR_FREE(state);
-        goto error;
-    }
-
-    if (VIR_ALLOC(state->callbacks) < 0)
-        goto error;
-
-    if (!(state->queue = virDomainEventQueueNew()))
-        goto error;
-
-    state->timer = -1;
-
-    return state;
-
-error:
-    virDomainEventStateFree(state);
-    return NULL;
-}
-
-static virDomainEventPtr virDomainEventNewInternal(int eventID,
-                                                   int id,
-                                                   const char *name,
-                                                   const unsigned char *uuid)
+ * virDomainEventStateDeregister:
+ * @conn: connection to associate with callback
+ * @state: object event state
+ * @callback: function to remove from event
+ *
+ * Unregister the function @callback with connection @conn,
+ * from @state, for lifecycle events.
+ *
+ * Returns: the number of lifecycle callbacks still registered, or -1 on error
+ */
+int
+virDomainEventStateDeregister(virConnectPtr conn,
+                              virObjectEventStatePtr state,
+                              virConnectDomainEventCallback callback)
 {
-    virDomainEventPtr event;
+    int ret;
 
-    if (VIR_ALLOC(event) < 0)
-        return NULL;
+    virObjectEventStateLock(state);
+    if (state->isDispatching)
+        ret = virDomainEventCallbackListMarkDelete(conn,
+                                                   state->callbacks, callback);
+    else
+        ret = virDomainEventCallbackListRemove(conn, state->callbacks, callback);
 
-    event->eventID = eventID;
-    if (VIR_STRDUP(event->dom.name, name) < 0) {
-        VIR_FREE(event);
-        return NULL;
+    if (state->callbacks->count == 0 &&
+        state->timer != -1) {
+        virEventRemoveTimeout(state->timer);
+        state->timer = -1;
+        virObjectEventQueueClear(state->queue);
     }
-    event->dom.id = id;
-    memcpy(event->dom.uuid, uuid, VIR_UUID_BUFLEN);
 
-    return event;
+    virObjectEventStateUnlock(state);
+    return ret;
 }
 
-virDomainEventPtr virDomainEventNew(int id, const char *name,
+
+virObjectEventPtr virDomainEventNew(int id, const char *name,
                                     const unsigned char *uuid,
                                     int type, int detail)
 {
-    virDomainEventPtr event = virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+    virObjectEventPtr event = virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                                                         id, name, uuid);
 
     if (event) {
-        event->data.lifecycle.type = type;
-        event->data.lifecycle.detail = detail;
+        event->data.domainData.lifecycle.type = type;
+        event->data.domainData.lifecycle.detail = detail;
     }
 
     return event;
 }
 
-virDomainEventPtr virDomainEventNewFromDom(virDomainPtr dom, int type, int detail)
+virObjectEventPtr virDomainEventNewFromDom(virDomainPtr dom, int type, int detail)
 {
     return virDomainEventNew(dom->id, dom->name, dom->uuid, type, detail);
 }
 
-virDomainEventPtr virDomainEventNewFromObj(virDomainObjPtr obj, int type, int detail)
+virObjectEventPtr virDomainEventNewFromObj(virDomainObjPtr obj, int type, int detail)
 {
     return virDomainEventNewFromDef(obj->def, type, detail);
 }
 
-virDomainEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int detail)
+virObjectEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int detail)
 {
     return virDomainEventNew(def->id, def->name, def->uuid, type, detail);
 }
 
-virDomainEventPtr virDomainEventRebootNew(int id, const char *name,
+virObjectEventPtr virDomainEventRebootNew(int id, const char *name,
                                           const unsigned char *uuid)
 {
-    return virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
+    return virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
                                      id, name, uuid);
 }
 
-virDomainEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom)
+virObjectEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom)
 {
-    return virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
+    return virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
                                      dom->id, dom->name, dom->uuid);
 }
 
-virDomainEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj)
+virObjectEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj)
 {
-    return virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
+    return virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
                                      obj->def->id, obj->def->name, obj->def->uuid);
 }
 
-virDomainEventPtr virDomainEventRTCChangeNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventRTCChangeNewFromDom(virDomainPtr dom,
                                                     long long offset)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
                                   dom->id, dom->name, dom->uuid);
 
     if (ev)
-        ev->data.rtcChange.offset = offset;
+        ev->data.domainData.rtcChange.offset = offset;
 
     return ev;
 }
-virDomainEventPtr virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj,
                                                     long long offset)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
                                   obj->def->id, obj->def->name, obj->def->uuid);
 
     if (ev)
-        ev->data.rtcChange.offset = offset;
+        ev->data.domainData.rtcChange.offset = offset;
 
     return ev;
 }
 
-virDomainEventPtr virDomainEventWatchdogNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventWatchdogNewFromDom(virDomainPtr dom,
                                                    int action)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_WATCHDOG,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_WATCHDOG,
                                   dom->id, dom->name, dom->uuid);
 
     if (ev)
-        ev->data.watchdog.action = action;
+        ev->data.domainData.watchdog.action = action;
 
     return ev;
 }
-virDomainEventPtr virDomainEventWatchdogNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventWatchdogNewFromObj(virDomainObjPtr obj,
                                                    int action)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_WATCHDOG,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_WATCHDOG,
                                   obj->def->id, obj->def->name, obj->def->uuid);
 
     if (ev)
-        ev->data.watchdog.action = action;
+        ev->data.domainData.watchdog.action = action;
 
     return ev;
 }
 
-static virDomainEventPtr virDomainEventIOErrorNewFromDomImpl(int event,
+static virObjectEventPtr virDomainEventIOErrorNewFromDomImpl(int event,
                                                              virDomainPtr dom,
                                                              const char *srcPath,
                                                              const char *devAlias,
                                                              int action,
                                                              const char *reason)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(event,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(event,
                                   dom->id, dom->name, dom->uuid);
 
     if (ev) {
-        ev->data.ioError.action = action;
-        if (VIR_STRDUP(ev->data.ioError.srcPath, srcPath) < 0 ||
-            VIR_STRDUP(ev->data.ioError.devAlias, devAlias) < 0 ||
-            VIR_STRDUP(ev->data.ioError.reason, reason) < 0) {
-            virDomainEventFree(ev);
+        ev->data.domainData.ioError.action = action;
+        if (VIR_STRDUP(ev->data.domainData.ioError.srcPath, srcPath) < 0 ||
+            VIR_STRDUP(ev->data.domainData.ioError.devAlias, devAlias) < 0 ||
+            VIR_STRDUP(ev->data.domainData.ioError.reason, reason) < 0) {
+            virObjectEventFree(ev);
             ev = NULL;
         }
     }
@@ -797,23 +346,23 @@ static virDomainEventPtr virDomainEventIOErrorNewFromDomImpl(int event,
     return ev;
 }
 
-static virDomainEventPtr virDomainEventIOErrorNewFromObjImpl(int event,
+static virObjectEventPtr virDomainEventIOErrorNewFromObjImpl(int event,
                                                              virDomainObjPtr obj,
                                                              const char *srcPath,
                                                              const char *devAlias,
                                                              int action,
                                                              const char *reason)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(event,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(event,
                                   obj->def->id, obj->def->name, obj->def->uuid);
 
     if (ev) {
-        ev->data.ioError.action = action;
-        if (VIR_STRDUP(ev->data.ioError.srcPath, srcPath) < 0 ||
-            VIR_STRDUP(ev->data.ioError.devAlias, devAlias) < 0 ||
-            VIR_STRDUP(ev->data.ioError.reason, reason) < 0) {
-            virDomainEventFree(ev);
+        ev->data.domainData.ioError.action = action;
+        if (VIR_STRDUP(ev->data.domainData.ioError.srcPath, srcPath) < 0 ||
+            VIR_STRDUP(ev->data.domainData.ioError.devAlias, devAlias) < 0 ||
+            VIR_STRDUP(ev->data.domainData.ioError.reason, reason) < 0) {
+            virObjectEventFree(ev);
             ev = NULL;
         }
     }
@@ -821,7 +370,7 @@ static virDomainEventPtr virDomainEventIOErrorNewFromObjImpl(int event,
     return ev;
 }
 
-virDomainEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
                                                   const char *srcPath,
                                                   const char *devAlias,
                                                   int action)
@@ -831,7 +380,7 @@ virDomainEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
                                                action, NULL);
 }
 
-virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
                                                   const char *srcPath,
                                                   const char *devAlias,
                                                   int action)
@@ -841,7 +390,7 @@ virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
                                                action, NULL);
 }
 
-virDomainEventPtr virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
                                                         const char *srcPath,
                                                         const char *devAlias,
                                                         int action,
@@ -852,7 +401,7 @@ virDomainEventPtr virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
                                                action, reason);
 }
 
-virDomainEventPtr virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
                                                         const char *srcPath,
                                                         const char *devAlias,
                                                         int action,
@@ -864,77 +413,77 @@ virDomainEventPtr virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
 }
 
 
-virDomainEventPtr virDomainEventGraphicsNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventGraphicsNewFromDom(virDomainPtr dom,
                                                    int phase,
                                                    virDomainEventGraphicsAddressPtr local,
                                                    virDomainEventGraphicsAddressPtr remote,
                                                    const char *authScheme,
                                                    virDomainEventGraphicsSubjectPtr subject)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_GRAPHICS,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_GRAPHICS,
                                   dom->id, dom->name, dom->uuid);
 
     if (ev) {
-        ev->data.graphics.phase = phase;
-        if (VIR_STRDUP(ev->data.graphics.authScheme, authScheme) < 0) {
-            virDomainEventFree(ev);
+        ev->data.domainData.graphics.phase = phase;
+        if (VIR_STRDUP(ev->data.domainData.graphics.authScheme, authScheme) < 0) {
+            virObjectEventFree(ev);
             return NULL;
         }
-        ev->data.graphics.local = local;
-        ev->data.graphics.remote = remote;
-        ev->data.graphics.subject = subject;
+        ev->data.domainData.graphics.local = local;
+        ev->data.domainData.graphics.remote = remote;
+        ev->data.domainData.graphics.subject = subject;
     }
 
     return ev;
 }
 
-virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
                                                    int phase,
                                                    virDomainEventGraphicsAddressPtr local,
                                                    virDomainEventGraphicsAddressPtr remote,
                                                    const char *authScheme,
                                                    virDomainEventGraphicsSubjectPtr subject)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_GRAPHICS,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_GRAPHICS,
                                   obj->def->id, obj->def->name, obj->def->uuid);
 
     if (ev) {
-        ev->data.graphics.phase = phase;
-        if (VIR_STRDUP(ev->data.graphics.authScheme, authScheme) < 0) {
-            virDomainEventFree(ev);
+        ev->data.domainData.graphics.phase = phase;
+        if (VIR_STRDUP(ev->data.domainData.graphics.authScheme, authScheme) < 0) {
+            virObjectEventFree(ev);
             return NULL;
         }
-        ev->data.graphics.local = local;
-        ev->data.graphics.remote = remote;
-        ev->data.graphics.subject = subject;
+        ev->data.domainData.graphics.local = local;
+        ev->data.domainData.graphics.remote = remote;
+        ev->data.domainData.graphics.subject = subject;
     }
 
     return ev;
 }
 
-static virDomainEventPtr
+static virObjectEventPtr
 virDomainEventBlockJobNew(int id, const char *name, unsigned char *uuid,
                           const char *path, int type, int status)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
                                   id, name, uuid);
 
     if (ev) {
-        if (VIR_STRDUP(ev->data.blockJob.path, path) < 0) {
-            virDomainEventFree(ev);
+        if (VIR_STRDUP(ev->data.domainData.blockJob.path, path) < 0) {
+            virObjectEventFree(ev);
             return NULL;
         }
-        ev->data.blockJob.type = type;
-        ev->data.blockJob.status = status;
+        ev->data.domainData.blockJob.type = type;
+        ev->data.domainData.blockJob.status = status;
     }
 
     return ev;
 }
 
-virDomainEventPtr virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
                                                    const char *path,
                                                    int type,
                                                    int status)
@@ -943,7 +492,7 @@ virDomainEventPtr virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
                                      obj->def->uuid, path, type, status);
 }
 
-virDomainEventPtr virDomainEventBlockJobNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventBlockJobNewFromDom(virDomainPtr dom,
                                                    const char *path,
                                                    int type,
                                                    int status)
@@ -952,55 +501,55 @@ virDomainEventPtr virDomainEventBlockJobNewFromDom(virDomainPtr dom,
                                      path, type, status);
 }
 
-virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom)
+virObjectEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
                                   dom->id, dom->name, dom->uuid);
     return ev;
 }
 
 
-virDomainEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj)
+virObjectEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
                                   obj->def->id, obj->def->name, obj->def->uuid);
     return ev;
 }
 
-static virDomainEventPtr
+static virObjectEventPtr
 virDomainEventDiskChangeNew(int id, const char *name,
                             unsigned char *uuid,
                             const char *oldSrcPath,
                             const char *newSrcPath,
                             const char *devAlias, int reason)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
                                   id, name, uuid);
 
     if (ev) {
-        if (VIR_STRDUP(ev->data.diskChange.devAlias, devAlias) < 0)
+        if (VIR_STRDUP(ev->data.domainData.diskChange.devAlias, devAlias) < 0)
             goto error;
 
-        if (VIR_STRDUP(ev->data.diskChange.oldSrcPath, oldSrcPath) < 0)
+        if (VIR_STRDUP(ev->data.domainData.diskChange.oldSrcPath, oldSrcPath) < 0)
             goto error;
 
-        if (VIR_STRDUP(ev->data.diskChange.newSrcPath, newSrcPath) < 0)
+        if (VIR_STRDUP(ev->data.domainData.diskChange.newSrcPath, newSrcPath) < 0)
             goto error;
 
-        ev->data.diskChange.reason = reason;
+        ev->data.domainData.diskChange.reason = reason;
     }
 
     return ev;
 
 error:
-    virDomainEventFree(ev);
+    virObjectEventFree(ev);
     return NULL;
 }
 
-virDomainEventPtr virDomainEventDiskChangeNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventDiskChangeNewFromObj(virDomainObjPtr obj,
                                                      const char *oldSrcPath,
                                                      const char *newSrcPath,
                                                      const char *devAlias,
@@ -1011,7 +560,7 @@ virDomainEventPtr virDomainEventDiskChangeNewFromObj(virDomainObjPtr obj,
                                        newSrcPath, devAlias, reason);
 }
 
-virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
                                                      const char *oldSrcPath,
                                                      const char *newSrcPath,
                                                      const char *devAlias,
@@ -1022,31 +571,31 @@ virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
                                        devAlias, reason);
 }
 
-static virDomainEventPtr
+static virObjectEventPtr
 virDomainEventTrayChangeNew(int id, const char *name,
                             unsigned char *uuid,
                             const char *devAlias,
                             int reason)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_TRAY_CHANGE,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_TRAY_CHANGE,
                                   id, name, uuid);
 
     if (ev) {
-        if (VIR_STRDUP(ev->data.trayChange.devAlias, devAlias) < 0)
+        if (VIR_STRDUP(ev->data.domainData.trayChange.devAlias, devAlias) < 0)
             goto error;
 
-        ev->data.trayChange.reason = reason;
+        ev->data.domainData.trayChange.reason = reason;
     }
 
     return ev;
 
 error:
-    virDomainEventFree(ev);
+    virObjectEventFree(ev);
     return NULL;
 }
 
-virDomainEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
                                                      const char *devAlias,
                                                      int reason)
 {
@@ -1057,7 +606,7 @@ virDomainEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
                                        reason);
 }
 
-virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
                                                      const char *devAlias,
                                                      int reason)
 {
@@ -1065,18 +614,18 @@ virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
                                        devAlias, reason);
 }
 
-static virDomainEventPtr
+static virObjectEventPtr
 virDomainEventPMWakeupNew(int id, const char *name,
                           unsigned char *uuid)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMWAKEUP,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_PMWAKEUP,
                                   id, name, uuid);
 
     return ev;
 }
 
-virDomainEventPtr
+virObjectEventPtr
 virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj)
 {
     return virDomainEventPMWakeupNew(obj->def->id,
@@ -1084,24 +633,24 @@ virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj)
                                      obj->def->uuid);
 }
 
-virDomainEventPtr
+virObjectEventPtr
 virDomainEventPMWakeupNewFromDom(virDomainPtr dom)
 {
     return virDomainEventPMWakeupNew(dom->id, dom->name, dom->uuid);
 }
 
-static virDomainEventPtr
+static virObjectEventPtr
 virDomainEventPMSuspendNew(int id, const char *name,
                            unsigned char *uuid)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND,
                                   id, name, uuid);
 
     return ev;
 }
 
-virDomainEventPtr
+virObjectEventPtr
 virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj)
 {
     return virDomainEventPMSuspendNew(obj->def->id,
@@ -1109,23 +658,23 @@ virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj)
                                       obj->def->uuid);
 }
 
-virDomainEventPtr
+virObjectEventPtr
 virDomainEventPMSuspendNewFromDom(virDomainPtr dom)
 {
     return virDomainEventPMSuspendNew(dom->id, dom->name, dom->uuid);
 }
 
-static virDomainEventPtr
+static virObjectEventPtr
 virDomainEventPMSuspendDiskNew(int id, const char *name,
                                unsigned char *uuid)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK,
                                   id, name, uuid);
     return ev;
 }
 
-virDomainEventPtr
+virObjectEventPtr
 virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj)
 {
     return virDomainEventPMSuspendDiskNew(obj->def->id,
@@ -1133,60 +682,60 @@ virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj)
                                           obj->def->uuid);
 }
 
-virDomainEventPtr
+virObjectEventPtr
 virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom)
 {
     return virDomainEventPMSuspendDiskNew(dom->id, dom->name, dom->uuid);
 }
 
-virDomainEventPtr virDomainEventBalloonChangeNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventBalloonChangeNewFromDom(virDomainPtr dom,
                                                         unsigned long long actual)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
                                   dom->id, dom->name, dom->uuid);
 
     if (ev)
-        ev->data.balloonChange.actual = actual;
+        ev->data.domainData.balloonChange.actual = actual;
 
     return ev;
 }
-virDomainEventPtr virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj,
                                                         unsigned long long actual)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
                                   obj->def->id, obj->def->name, obj->def->uuid);
 
     if (ev)
-        ev->data.balloonChange.actual = actual;
+        ev->data.domainData.balloonChange.actual = actual;
 
     return ev;
 }
 
-static virDomainEventPtr
+static virObjectEventPtr
 virDomainEventDeviceRemovedNew(int id,
                                const char *name,
                                unsigned char *uuid,
                                const char *devAlias)
 {
-    virDomainEventPtr ev =
-        virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
+    virObjectEventPtr ev =
+        virObjectEventNewInternal(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
                                   id, name, uuid);
 
     if (ev) {
-        if (VIR_STRDUP(ev->data.deviceRemoved.devAlias, devAlias) < 0)
+        if (VIR_STRDUP(ev->data.domainData.deviceRemoved.devAlias, devAlias) < 0)
             goto error;
     }
 
     return ev;
 
 error:
-    virDomainEventFree(ev);
+    virObjectEventFree(ev);
     return NULL;
 }
 
-virDomainEventPtr
+virObjectEventPtr
 virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
                                       const char *devAlias)
 {
@@ -1194,7 +743,7 @@ virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
                                           obj->def->uuid, devAlias);
 }
 
-virDomainEventPtr
+virObjectEventPtr
 virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
                                       const char *devAlias)
 {
@@ -1202,373 +751,11 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
                                           devAlias);
 }
 
-/**
- * virDomainEventQueuePush:
- * @evtQueue: the dom event queue
- * @event: the event to add
- *
- * Internal function to push to the back of a virDomainEventQueue
- *
- * Returns: 0 on success, -1 on failure
- */
-static int
-virDomainEventQueuePush(virDomainEventQueuePtr evtQueue,
-                        virDomainEventPtr event)
-{
-    if (!evtQueue) {
-        return -1;
-    }
-
-    /* Make space on queue */
-    if (VIR_REALLOC_N(evtQueue->events,
-                      evtQueue->count + 1) < 0)
-        return -1;
-
-    evtQueue->events[evtQueue->count] = event;
-    evtQueue->count++;
-    return 0;
-}
-
-
-typedef void (*virDomainEventDispatchFunc)(virConnectPtr conn,
-                                           virDomainEventPtr event,
-                                           virConnectDomainEventGenericCallback cb,
-                                           void *cbopaque,
-                                           void *opaque);
-
-
-static void
-virDomainEventDispatchDefaultFunc(virConnectPtr conn,
-                                  virDomainEventPtr event,
-                                  virConnectDomainEventGenericCallback cb,
-                                  void *cbopaque,
-                                  void *opaque ATTRIBUTE_UNUSED)
-{
-    virDomainPtr dom = virGetDomain(conn, event->dom.name, event->dom.uuid);
-    if (!dom)
-        return;
-    dom->id = event->dom.id;
-
-    switch ((virDomainEventID) event->eventID) {
-    case VIR_DOMAIN_EVENT_ID_LIFECYCLE:
-        ((virConnectDomainEventCallback)cb)(conn, dom,
-                                            event->data.lifecycle.type,
-                                            event->data.lifecycle.detail,
-                                            cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_REBOOT:
-        (cb)(conn, dom,
-             cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_RTC_CHANGE:
-        ((virConnectDomainEventRTCChangeCallback)cb)(conn, dom,
-                                                     event->data.rtcChange.offset,
-                                                     cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_WATCHDOG:
-        ((virConnectDomainEventWatchdogCallback)cb)(conn, dom,
-                                                    event->data.watchdog.action,
-                                                    cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_IO_ERROR:
-        ((virConnectDomainEventIOErrorCallback)cb)(conn, dom,
-                                                   event->data.ioError.srcPath,
-                                                   event->data.ioError.devAlias,
-                                                   event->data.ioError.action,
-                                                   cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
-        ((virConnectDomainEventIOErrorReasonCallback)cb)(conn, dom,
-                                                         event->data.ioError.srcPath,
-                                                         event->data.ioError.devAlias,
-                                                         event->data.ioError.action,
-                                                         event->data.ioError.reason,
-                                                         cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_GRAPHICS:
-        ((virConnectDomainEventGraphicsCallback)cb)(conn, dom,
-                                                    event->data.graphics.phase,
-                                                    event->data.graphics.local,
-                                                    event->data.graphics.remote,
-                                                    event->data.graphics.authScheme,
-                                                    event->data.graphics.subject,
-                                                    cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
-        (cb)(conn, dom,
-             cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
-        ((virConnectDomainEventBlockJobCallback)cb)(conn, dom,
-                                                    event->data.blockJob.path,
-                                                    event->data.blockJob.type,
-                                                    event->data.blockJob.status,
-                                                    cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
-        ((virConnectDomainEventDiskChangeCallback)cb)(conn, dom,
-                                                      event->data.diskChange.oldSrcPath,
-                                                      event->data.diskChange.newSrcPath,
-                                                      event->data.diskChange.devAlias,
-                                                      event->data.diskChange.reason,
-                                                      cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
-        ((virConnectDomainEventTrayChangeCallback)cb)(conn, dom,
-                                                      event->data.trayChange.devAlias,
-                                                      event->data.trayChange.reason,
-                                                      cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_PMWAKEUP:
-        ((virConnectDomainEventPMWakeupCallback)cb)(conn, dom, 0, cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_PMSUSPEND:
-        ((virConnectDomainEventPMSuspendCallback)cb)(conn, dom, 0, cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
-        ((virConnectDomainEventBalloonChangeCallback)cb)(conn, dom,
-                                                         event->data.balloonChange.actual,
-                                                         cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
-        ((virConnectDomainEventPMSuspendDiskCallback)cb)(conn, dom, 0, cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
-        ((virConnectDomainEventDeviceRemovedCallback)cb)(conn, dom,
-                                                         event->data.deviceRemoved.devAlias,
-                                                         cbopaque);
-        goto cleanup;
-
-    case VIR_DOMAIN_EVENT_ID_LAST:
-        break;
-    }
-
-    VIR_WARN("Unexpected event ID %d", event->eventID);
-
-cleanup:
-    virDomainFree(dom);
-}
-
-
-static int virDomainEventDispatchMatchCallback(virDomainEventPtr event,
-                                               virDomainEventCallbackPtr cb)
-{
-    if (!cb)
-        return 0;
-    if (cb->deleted)
-        return 0;
-    if (cb->eventID != event->eventID)
-        return 0;
-
-    if (cb->dom) {
-        /* Deliberately ignoring 'id' for matching, since that
-         * will cause problems when a domain switches between
-         * running & shutoff states & ignoring 'name' since
-         * Xen sometimes renames guests during migration, thus
-         * leaving 'uuid' as the only truly reliable ID we can use*/
-
-        if (memcmp(event->dom.uuid, cb->dom->uuid, VIR_UUID_BUFLEN) == 0)
-            return 1;
-
-        return 0;
-    } else {
-        return 1;
-    }
-}
-
-
-static void
-virDomainEventDispatch(virDomainEventPtr event,
-                       virDomainEventCallbackListPtr callbacks,
-                       virDomainEventDispatchFunc dispatch,
-                       void *opaque)
-{
-    size_t i;
-    /* Cache this now, since we may be dropping the lock,
-       and have more callbacks added. We're guaranteed not
-       to have any removed */
-    int cbCount = callbacks->count;
-
-    for (i = 0; i < cbCount; i++) {
-        if (!virDomainEventDispatchMatchCallback(event, callbacks->callbacks[i]))
-            continue;
-
-        (*dispatch)(callbacks->callbacks[i]->conn,
-                    event,
-                    callbacks->callbacks[i]->cb,
-                    callbacks->callbacks[i]->opaque,
-                    opaque);
-    }
-}
-
-
-static void
-virDomainEventQueueDispatch(virDomainEventQueuePtr queue,
-                            virDomainEventCallbackListPtr callbacks,
-                            virDomainEventDispatchFunc dispatch,
-                            void *opaque)
-{
-    size_t i;
-
-    for (i = 0; i < queue->count; i++) {
-        virDomainEventDispatch(queue->events[i], callbacks, dispatch, opaque);
-        virDomainEventFree(queue->events[i]);
-    }
-    VIR_FREE(queue->events);
-    queue->count = 0;
-}
-
-void
-virDomainEventStateQueue(virDomainEventStatePtr state,
-                         virDomainEventPtr event)
-{
-    if (state->timer < 0) {
-        virDomainEventFree(event);
-        return;
-    }
-
-    virDomainEventStateLock(state);
-
-    if (virDomainEventQueuePush(state->queue, event) < 0) {
-        VIR_DEBUG("Error adding event to queue");
-        virDomainEventFree(event);
-    }
-
-    if (state->queue->count == 1)
-        virEventUpdateTimeout(state->timer, 0);
-    virDomainEventStateUnlock(state);
-}
-
-
-static void
-virDomainEventStateDispatchFunc(virConnectPtr conn,
-                                virDomainEventPtr event,
-                                virConnectDomainEventGenericCallback cb,
-                                void *cbopaque,
-                                void *opaque)
-{
-    virDomainEventStatePtr state = opaque;
-
-    /* Drop the lock whle dispatching, for sake of re-entrancy */
-    virDomainEventStateUnlock(state);
-    virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL);
-    virDomainEventStateLock(state);
-}
-
-
-static void
-virDomainEventStateFlush(virDomainEventStatePtr state)
-{
-    virDomainEventQueue tempQueue;
-
-    virDomainEventStateLock(state);
-    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,
-                                virDomainEventStateDispatchFunc,
-                                state);
-
-    /* Purge any deleted callbacks */
-    virDomainEventCallbackListPurgeMarked(state->callbacks);
-
-    state->isDispatching = false;
-    virDomainEventStateUnlock(state);
-}
-
-
-/**
- * virDomainEventStateRegister:
- * @conn: connection to associate with callback
- * @state: domain event state
- * @callback: function to remove from event
- * @opaque: data blob to pass to callback
- * @freecb: callback to free @opaque
- *
- * Register the function @callback with connection @conn,
- * from @state, for lifecycle events.
- *
- * Returns: the number of lifecycle callbacks now registered, or -1 on error
- */
-int
-virDomainEventStateRegister(virConnectPtr conn,
-                            virDomainEventStatePtr state,
-                            virConnectDomainEventCallback callback,
-                            void *opaque,
-                            virFreeCallback freecb)
-{
-    int ret = -1;
-
-    virDomainEventStateLock(state);
-
-    if ((state->callbacks->count == 0) &&
-        (state->timer == -1) &&
-        (state->timer = virEventAddTimeout(-1,
-                                           virDomainEventTimer,
-                                           state,
-                                           NULL)) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("could not initialize domain event timer"));
-        goto cleanup;
-    }
-
-    ret = virDomainEventCallbackListAdd(conn, state->callbacks,
-                                        callback, opaque, freecb);
-
-    if (ret == -1 &&
-        state->callbacks->count == 0 &&
-        state->timer != -1) {
-        virEventRemoveTimeout(state->timer);
-        state->timer = -1;
-    }
-
-cleanup:
-    virDomainEventStateUnlock(state);
-    return ret;
-}
-
 
-/**
- * virDomainEventStateRegisterID:
- * @conn: connection to associate with callback
- * @state: domain event state
- * @eventID: ID of the event type to register for
- * @cb: function to remove from event
- * @opaque: data blob to pass to callback
- * @freecb: callback to free @opaque
- * @callbackID: filled with callback ID
- *
- * Register the function @callbackID with connection @conn,
- * from @state, for events of type @eventID.
- *
- * Returns: the number of callbacks now registered, or -1 on error
- */
+/* Kept for compatibility reasons */
 int
 virDomainEventStateRegisterID(virConnectPtr conn,
-                              virDomainEventStatePtr state,
+                              virObjectEventStatePtr state,
                               virDomainPtr dom,
                               int eventID,
                               virConnectDomainEventGenericCallback cb,
@@ -1576,134 +763,14 @@ virDomainEventStateRegisterID(virConnectPtr conn,
                               virFreeCallback freecb,
                               int *callbackID)
 {
-    int ret = -1;
-
-    virDomainEventStateLock(state);
-
-    if ((state->callbacks->count == 0) &&
-        (state->timer == -1) &&
-        (state->timer = virEventAddTimeout(-1,
-                                           virDomainEventTimer,
-                                           state,
-                                           NULL)) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("could not initialize domain event timer"));
-        goto cleanup;
-    }
-
-    ret = virDomainEventCallbackListAddID(conn, state->callbacks,
-                                          dom, eventID, cb, opaque, freecb,
-                                          callbackID);
-
-    if (ret == -1 &&
-        state->callbacks->count == 0 &&
-        state->timer != -1) {
-        virEventRemoveTimeout(state->timer);
-        state->timer = -1;
-    }
-
-cleanup:
-    virDomainEventStateUnlock(state);
-    return ret;
-}
-
-
-/**
- * virDomainEventStateDeregister:
- * @conn: connection to associate with callback
- * @state: domain event state
- * @callback: function to remove from event
- *
- * Unregister the function @callback with connection @conn,
- * from @state, for lifecycle events.
- *
- * Returns: the number of lifecycle callbacks still registered, or -1 on error
- */
-int
-virDomainEventStateDeregister(virConnectPtr conn,
-                              virDomainEventStatePtr state,
-                              virConnectDomainEventCallback callback)
-{
-    int ret;
-
-    virDomainEventStateLock(state);
-    if (state->isDispatching)
-        ret = virDomainEventCallbackListMarkDelete(conn,
-                                                   state->callbacks, callback);
-    else
-        ret = virDomainEventCallbackListRemove(conn, state->callbacks, callback);
-
-    if (state->callbacks->count == 0 &&
-        state->timer != -1) {
-        virEventRemoveTimeout(state->timer);
-        state->timer = -1;
-        virDomainEventQueueClear(state->queue);
-    }
-
-    virDomainEventStateUnlock(state);
-    return ret;
-}
-
-
-/**
- * virDomainEventStateDeregisterID:
- * @conn: connection to associate with callback
- * @state: domain event state
- * @callbackID: ID of the function to remove from event
- *
- * Unregister the function @callbackID with connection @conn,
- * from @state, for events.
- *
- * Returns: the number of callbacks still registered, or -1 on error
- */
-int
-virDomainEventStateDeregisterID(virConnectPtr conn,
-                                virDomainEventStatePtr state,
-                                int callbackID)
-{
-    int ret;
-
-    virDomainEventStateLock(state);
-    if (state->isDispatching)
-        ret = virDomainEventCallbackListMarkDeleteID(conn,
-                                                     state->callbacks, callbackID);
+    if (dom)
+        return virObjectEventStateRegisterID(conn, state, dom->uuid, dom->name,
+                                             dom->id, eventID,
+                                             VIR_OBJECT_EVENT_CALLBACK(cb),
+                                             opaque, freecb, callbackID);
     else
-        ret = virDomainEventCallbackListRemoveID(conn,
-                                                 state->callbacks, callbackID);
-
-    if (state->callbacks->count == 0 &&
-        state->timer != -1) {
-        virEventRemoveTimeout(state->timer);
-        state->timer = -1;
-        virDomainEventQueueClear(state->queue);
-    }
-
-    virDomainEventStateUnlock(state);
-    return ret;
-}
-
-
-/**
- * virDomainEventStateEventID:
- * @conn: connection associated with the callback
- * @state: domain event state
- * @callbackID: the callback to query
- *
- * Query what event ID type is associated with the
- * callback @callbackID for connection @conn
- *
- * Returns 0 on success, -1 on error
- */
-int
-virDomainEventStateEventID(virConnectPtr conn,
-                           virDomainEventStatePtr state,
-                           int callbackID)
-{
-    int ret;
-
-    virDomainEventStateLock(state);
-    ret = virDomainEventCallbackListEventID(conn,
-                                            state->callbacks, callbackID);
-    virDomainEventStateUnlock(state);
-    return ret;
+        return virObjectEventStateRegisterID(conn, state, NULL, NULL, 0,
+                                             eventID,
+                                             VIR_OBJECT_EVENT_CALLBACK(cb),
+                                             opaque, freecb, callbackID);
 }
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index f6b957d..c8928c7 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -26,135 +26,112 @@
 #ifndef __DOMAIN_EVENT_H__
 # define __DOMAIN_EVENT_H__
 
+# include "object_event.h"
 # include "domain_conf.h"
 
-typedef struct _virDomainEventCallback virDomainEventCallback;
-typedef virDomainEventCallback *virDomainEventCallbackPtr;
-
-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;
-
-typedef struct _virDomainEventQueue virDomainEventQueue;
-typedef virDomainEventQueue *virDomainEventQueuePtr;
-
-typedef struct _virDomainEventState virDomainEventState;
-typedef virDomainEventState *virDomainEventStatePtr;
+int virDomainEventStateRegister(virConnectPtr conn,
+                                virObjectEventStatePtr state,
+                                virConnectDomainEventCallback callback,
+                                void *opaque,
+                                virFreeCallback freecb)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+int
+virDomainEventStateDeregister(virConnectPtr conn,
+                              virObjectEventStatePtr state,
+                              virConnectDomainEventCallback callback)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
-virDomainEventPtr virDomainEventNew(int id, const char *name, const unsigned char *uuid, int type, int detail);
-virDomainEventPtr virDomainEventNewFromDom(virDomainPtr dom, int type, int detail);
-virDomainEventPtr virDomainEventNewFromObj(virDomainObjPtr obj, int type, int detail);
-virDomainEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int detail);
+virObjectEventPtr virDomainEventNew(int id, const char *name, const unsigned char *uuid, int type, int detail);
+virObjectEventPtr virDomainEventNewFromDom(virDomainPtr dom, int type, int detail);
+virObjectEventPtr virDomainEventNewFromObj(virDomainObjPtr obj, int type, int detail);
+virObjectEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int detail);
 
-virDomainEventPtr virDomainEventRebootNew(int id, const char *name, const unsigned char *uuid);
-virDomainEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom);
-virDomainEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj);
+virObjectEventPtr virDomainEventRebootNew(int id, const char *name, const unsigned char *uuid);
+virObjectEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom);
+virObjectEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj);
 
-virDomainEventPtr virDomainEventRTCChangeNewFromDom(virDomainPtr dom, long long offset);
-virDomainEventPtr virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj, long long offset);
+virObjectEventPtr virDomainEventRTCChangeNewFromDom(virDomainPtr dom, long long offset);
+virObjectEventPtr virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj, long long offset);
 
-virDomainEventPtr virDomainEventWatchdogNewFromDom(virDomainPtr dom, int action);
-virDomainEventPtr virDomainEventWatchdogNewFromObj(virDomainObjPtr obj, int action);
+virObjectEventPtr virDomainEventWatchdogNewFromDom(virDomainPtr dom, int action);
+virObjectEventPtr virDomainEventWatchdogNewFromObj(virDomainObjPtr obj, int action);
 
-virDomainEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventIOErrorNewFromDom(virDomainPtr dom,
                                                   const char *srcPath,
                                                   const char *devAlias,
                                                   int action);
-virDomainEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
                                                   const char *srcPath,
                                                   const char *devAlias,
                                                   int action);
-virDomainEventPtr virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
                                                         const char *srcPath,
                                                         const char *devAlias,
                                                         int action,
                                                         const char *reason);
-virDomainEventPtr virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
                                                         const char *srcPath,
                                                         const char *devAlias,
                                                         int action,
                                                         const char *reason);
 
-virDomainEventPtr virDomainEventGraphicsNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventGraphicsNewFromDom(virDomainPtr dom,
                                                    int phase,
                                                    virDomainEventGraphicsAddressPtr local,
                                                    virDomainEventGraphicsAddressPtr remote,
                                                    const char *authScheme,
                                                    virDomainEventGraphicsSubjectPtr subject);
-virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
                                                    int phase,
                                                    virDomainEventGraphicsAddressPtr local,
                                                    virDomainEventGraphicsAddressPtr remote,
                                                    const char *authScheme,
                                                    virDomainEventGraphicsSubjectPtr subject);
-virDomainEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom);
-virDomainEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj);
+virObjectEventPtr virDomainEventControlErrorNewFromDom(virDomainPtr dom);
+virObjectEventPtr virDomainEventControlErrorNewFromObj(virDomainObjPtr obj);
 
-virDomainEventPtr virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
                                                     const char *path,
                                                     int type,
                                                     int status);
-virDomainEventPtr virDomainEventBlockJobNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventBlockJobNewFromDom(virDomainPtr dom,
                                                     const char *path,
                                                     int type,
                                                     int status);
 
-virDomainEventPtr virDomainEventDiskChangeNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventDiskChangeNewFromObj(virDomainObjPtr obj,
                                                      const char *oldSrcPath,
                                                      const char *newSrcPath,
                                                      const char *devAlias,
                                                      int reason);
-virDomainEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
                                                      const char *oldSrcPath,
                                                      const char *newSrcPath,
                                                      const char *devAlias,
                                                      int reason);
-virDomainEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
                                                      const char *devAlias,
                                                      int reason);
-virDomainEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
                                                      const char *devAlias,
                                                      int reason);
-virDomainEventPtr virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj);
-virDomainEventPtr virDomainEventPMWakeupNewFromDom(virDomainPtr dom);
-virDomainEventPtr virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj);
-virDomainEventPtr virDomainEventPMSuspendNewFromDom(virDomainPtr dom);
+virObjectEventPtr virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj);
+virObjectEventPtr virDomainEventPMWakeupNewFromDom(virDomainPtr dom);
+virObjectEventPtr virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj);
+virObjectEventPtr virDomainEventPMSuspendNewFromDom(virDomainPtr dom);
 
-virDomainEventPtr virDomainEventBalloonChangeNewFromDom(virDomainPtr dom, unsigned long long actual);
-virDomainEventPtr virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj, unsigned long long actual);
+virObjectEventPtr virDomainEventBalloonChangeNewFromDom(virDomainPtr dom, unsigned long long actual);
+virObjectEventPtr virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj, unsigned long long actual);
 
-virDomainEventPtr virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj);
-virDomainEventPtr virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom);
+virObjectEventPtr virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj);
+virObjectEventPtr virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom);
 
-virDomainEventPtr virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
+virObjectEventPtr virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
                                                         const char *devAlias);
-virDomainEventPtr virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
+virObjectEventPtr virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
                                                         const char *devAlias);
-
-void virDomainEventFree(virDomainEventPtr event);
-
-void virDomainEventStateFree(virDomainEventStatePtr state);
-virDomainEventStatePtr
-virDomainEventStateNew(void);
-
-void
-virDomainEventStateQueue(virDomainEventStatePtr state,
-                         virDomainEventPtr event)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-int virDomainEventStateRegister(virConnectPtr conn,
-                                virDomainEventStatePtr state,
-                                virConnectDomainEventCallback callback,
-                                void *opaque,
-                                virFreeCallback freecb)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 int virDomainEventStateRegisterID(virConnectPtr conn,
-                                  virDomainEventStatePtr state,
+                                  virObjectEventStatePtr state,
                                   virDomainPtr dom,
                                   int eventID,
                                   virConnectDomainEventGenericCallback cb,
@@ -162,20 +139,5 @@ int virDomainEventStateRegisterID(virConnectPtr conn,
                                   virFreeCallback freecb,
                                   int *callbackID)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5);
-int
-virDomainEventStateDeregister(virConnectPtr conn,
-                              virDomainEventStatePtr state,
-                              virConnectDomainEventCallback callback)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
-int
-virDomainEventStateDeregisterID(virConnectPtr conn,
-                                virDomainEventStatePtr state,
-                                int callbackID)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-int
-virDomainEventStateEventID(virConnectPtr conn,
-                           virDomainEventStatePtr state,
-                           int callbackID)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
 #endif
diff --git a/src/conf/object_event.c b/src/conf/object_event.c
new file mode 100644
index 0000000..46eb677
--- /dev/null
+++ b/src/conf/object_event.c
@@ -0,0 +1,918 @@
+/*
+ * domain_event.c: domain event queue processing helpers
+ *
+ * Copyright (C) 2010-2013 Red Hat, Inc.
+ * Copyright (C) 2008 VirtualIron
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ben Guthro
+ */
+
+#include <config.h>
+
+#include "object_event.h"
+#include "object_event_private.h"
+#include "virlog.h"
+#include "viralloc.h"
+#include "virerror.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+
+/**
+ * virObjectEventCallbackListFree:
+ * @list: event callback list head
+ *
+ * Free the memory in the domain event callback list
+ */
+static void
+virObjectEventCallbackListFree(virObjectEventCallbackListPtr list)
+{
+    size_t i;
+    if (!list)
+        return;
+
+    for (i=0; i<list->count; i++) {
+        virFreeCallback freecb = list->callbacks[i]->freecb;
+        if (freecb)
+            (*freecb)(list->callbacks[i]->opaque);
+        VIR_FREE(list->callbacks[i]);
+    }
+    VIR_FREE(list->callbacks);
+    VIR_FREE(list);
+}
+
+
+/**
+ * virObjectEventCallbackListRemoveID:
+ * @conn: pointer to the connection
+ * @cbList: the list
+ * @callback: the callback to remove
+ *
+ * Internal function to remove a callback from a virObjectEventCallbackListPtr
+ */
+static int
+virObjectEventCallbackListRemoveID(virConnectPtr conn,
+                                   virObjectEventCallbackListPtr cbList,
+                                   int callbackID)
+{
+    int ret = 0;
+    size_t i;
+    for (i = 0; i < cbList->count; i++) {
+        if (cbList->callbacks[i]->callbackID == callbackID &&
+            cbList->callbacks[i]->conn == conn) {
+            virFreeCallback freecb = cbList->callbacks[i]->freecb;
+            if (freecb)
+                (*freecb)(cbList->callbacks[i]->opaque);
+            virObjectUnref(cbList->callbacks[i]->conn);
+            VIR_FREE(cbList->callbacks[i]);
+
+            if (i < (cbList->count - 1))
+                memmove(cbList->callbacks + i,
+                        cbList->callbacks + i + 1,
+                        sizeof(*(cbList->callbacks)) *
+                                (cbList->count - (i + 1)));
+
+            if (VIR_REALLOC_N(cbList->callbacks,
+                              cbList->count - 1) < 0) {
+                ; /* Failure to reduce memory allocation isn't fatal */
+            }
+            cbList->count--;
+
+            for (i = 0; i < cbList->count; i++) {
+                if (!cbList->callbacks[i]->deleted)
+                    ret++;
+            }
+            return ret;
+        }
+    }
+
+    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                   _("could not find event callback for removal"));
+    return -1;
+}
+
+
+static int
+virObjectEventCallbackListMarkDeleteID(virConnectPtr conn,
+                                       virObjectEventCallbackListPtr cbList,
+                                       int callbackID)
+{
+    int ret = 0;
+    size_t i;
+    for (i = 0; i < cbList->count; i++) {
+        if (cbList->callbacks[i]->callbackID == callbackID &&
+            cbList->callbacks[i]->conn == conn) {
+            cbList->callbacks[i]->deleted = 1;
+            for (i = 0; i < cbList->count; i++) {
+                if (!cbList->callbacks[i]->deleted)
+                    ret++;
+            }
+            return ret;
+        }
+    }
+
+    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                   _("could not find event callback for deletion"));
+    return -1;
+}
+
+
+static int
+virObjectEventCallbackListPurgeMarked(virObjectEventCallbackListPtr cbList)
+{
+    int old_count = cbList->count;
+    int n;
+    for (n = 0; n < cbList->count; n++) {
+        if (cbList->callbacks[n]->deleted) {
+            virFreeCallback freecb = cbList->callbacks[n]->freecb;
+            if (freecb)
+                (*freecb)(cbList->callbacks[n]->opaque);
+            virObjectUnref(cbList->callbacks[n]->conn);
+            VIR_FREE(cbList->callbacks[n]);
+
+            if (n < (cbList->count - 1))
+                memmove(cbList->callbacks + n,
+                        cbList->callbacks + n + 1,
+                        sizeof(*(cbList->callbacks)) *
+                                (cbList->count - (n + 1)));
+            cbList->count--;
+            n--;
+        }
+    }
+    if (cbList->count < old_count &&
+        VIR_REALLOC_N(cbList->callbacks, cbList->count) < 0) {
+        ; /* Failure to reduce memory allocation isn't fatal */
+    }
+    return 0;
+}
+
+
+/**
+ * virObjectEventCallbackListAddID:
+ * @conn: pointer to the connection
+ * @cbList: the list
+ * @eventID: the event ID
+ * @callback: the callback to add
+ * @opaque: opaque data tio pass to callback
+ * @callbackID: filled with callback ID
+ *
+ * Internal function to add a callback from a virObjectEventCallbackListPtr
+ */
+int
+virObjectEventCallbackListAddID(virConnectPtr conn,
+                                virObjectEventCallbackListPtr cbList,
+                                unsigned char uuid[VIR_UUID_BUFLEN],
+                                const char *name,
+                                int id,
+                                int eventID,
+                                virConnectObjectEventGenericCallback callback,
+                                void *opaque,
+                                virFreeCallback freecb,
+                                int *callbackID)
+{
+    virObjectEventCallbackPtr event;
+    size_t i;
+    int ret = 0;
+
+    /* Check incoming */
+    if (!cbList) {
+        return -1;
+    }
+
+    /* check if we already have this callback on our list */
+    for (i = 0; i < cbList->count; i++) {
+        if (cbList->callbacks[i]->cb == VIR_OBJECT_EVENT_CALLBACK(callback) &&
+            cbList->callbacks[i]->eventID == eventID &&
+            cbList->callbacks[i]->conn == conn &&
+            ((uuid && cbList->callbacks[i]->dom &&
+              memcmp(cbList->callbacks[i]->dom->uuid,
+                     uuid, VIR_UUID_BUFLEN) == 0) ||
+             (!uuid && !cbList->callbacks[i]->dom))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("event callback already tracked"));
+            return -1;
+        }
+    }
+    /* Allocate new event */
+    if (VIR_ALLOC(event) < 0)
+        goto error;
+    event->conn = conn;
+    event->cb = callback;
+    event->eventID = eventID;
+    event->opaque = opaque;
+    event->freecb = freecb;
+
+    if (name && uuid && id > 0) {
+        if (VIR_ALLOC(event->dom) < 0)
+            goto error;
+        if (VIR_STRDUP(event->dom->name, name) < 0)
+            goto error;
+        memcpy(event->dom->uuid, uuid, VIR_UUID_BUFLEN);
+        event->dom->id = id;
+    }
+
+    /* Make space on list */
+    if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0)
+        goto error;
+
+    virObjectRef(event->conn);
+
+    cbList->callbacks[cbList->count] = event;
+    cbList->count++;
+
+    event->callbackID = cbList->nextID++;
+
+    for (i = 0; i < cbList->count; i++) {
+        if (cbList->callbacks[i]->eventID == eventID &&
+            cbList->callbacks[i]->conn == conn &&
+            !cbList->callbacks[i]->deleted)
+            ret++;
+    }
+
+    if (callbackID)
+        *callbackID = event->callbackID;
+
+    return ret;
+
+error:
+    if (event) {
+        if (event->dom)
+            VIR_FREE(event->dom->name);
+        VIR_FREE(event->dom);
+    }
+    VIR_FREE(event);
+    return -1;
+}
+
+static int
+virObjectEventCallbackListEventID(virConnectPtr conn,
+                                  virObjectEventCallbackListPtr cbList,
+                                  int callbackID)
+{
+    size_t i;
+
+    for (i = 0; i < cbList->count; i++) {
+        if (cbList->callbacks[i]->deleted)
+            continue;
+
+        if (cbList->callbacks[i]->callbackID == callbackID &&
+            cbList->callbacks[i]->conn == conn)
+            return cbList->callbacks[i]->eventID;
+    }
+
+    return -1;
+}
+
+static void
+virDomainEventDataFree(virObjectEventPtr event)
+{
+    switch (event->eventID) {
+    case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
+    case VIR_DOMAIN_EVENT_ID_IO_ERROR:
+        VIR_FREE(event->data.domainData.ioError.srcPath);
+        VIR_FREE(event->data.domainData.ioError.devAlias);
+        VIR_FREE(event->data.domainData.ioError.reason);
+        break;
+
+    case VIR_DOMAIN_EVENT_ID_GRAPHICS:
+        if (event->data.domainData.graphics.local) {
+            VIR_FREE(event->data.domainData.graphics.local->node);
+            VIR_FREE(event->data.domainData.graphics.local->service);
+            VIR_FREE(event->data.domainData.graphics.local);
+        }
+        if (event->data.domainData.graphics.remote) {
+            VIR_FREE(event->data.domainData.graphics.remote->node);
+            VIR_FREE(event->data.domainData.graphics.remote->service);
+            VIR_FREE(event->data.domainData.graphics.remote);
+        }
+        VIR_FREE(event->data.domainData.graphics.authScheme);
+        if (event->data.domainData.graphics.subject) {
+            size_t i;
+            for (i = 0; i < event->data.domainData.graphics.subject->nidentity; i++) {
+                VIR_FREE(event->data.domainData.graphics.subject->identities[i].type);
+                VIR_FREE(event->data.domainData.graphics.subject->identities[i].name);
+            }
+            VIR_FREE(event->data.domainData.graphics.subject);
+        }
+        break;
+
+    case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
+        VIR_FREE(event->data.domainData.blockJob.path);
+        break;
+
+    case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
+        VIR_FREE(event->data.domainData.diskChange.oldSrcPath);
+        VIR_FREE(event->data.domainData.diskChange.newSrcPath);
+        VIR_FREE(event->data.domainData.diskChange.devAlias);
+        break;
+    case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
+        VIR_FREE(event->data.domainData.trayChange.devAlias);
+        break;
+    case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
+        VIR_FREE(event->data.domainData.deviceRemoved.devAlias);
+        break;
+    }
+}
+
+void virObjectEventFree(virObjectEventPtr event)
+{
+    if (!event)
+        return;
+
+    int namespace = (event->eventID & 0xFF00) >> 8;
+    switch (namespace)
+    {
+        case VIR_EVENT_NAMESPACE_DOMAIN:
+            virDomainEventDataFree(event);
+            break;
+    }
+
+    VIR_FREE(event->dom.name);
+    VIR_FREE(event);
+}
+
+/**
+ * virObjectEventQueueClear:
+ * @queue: pointer to the queue
+ *
+ * Removes all elements from the queue
+ */
+void
+virObjectEventQueueClear(virObjectEventQueuePtr queue)
+{
+    size_t i;
+    if (!queue)
+        return;
+
+    for (i = 0; i < queue->count; i++) {
+        virObjectEventFree(queue->events[i]);
+    }
+    VIR_FREE(queue->events);
+    queue->count = 0;
+}
+
+/**
+ * virObjectEventQueueFree:
+ * @queue: pointer to the queue
+ *
+ * Free the memory in the queue. We process this like a list here
+ */
+static void
+virObjectEventQueueFree(virObjectEventQueuePtr queue)
+{
+    if (!queue)
+        return;
+
+    virObjectEventQueueClear(queue);
+    VIR_FREE(queue);
+}
+
+static virObjectEventQueuePtr
+virObjectEventQueueNew(void)
+{
+    virObjectEventQueuePtr ret;
+
+    ignore_value(VIR_ALLOC(ret));
+    return ret;
+}
+
+void
+virObjectEventStateLock(virObjectEventStatePtr state)
+{
+    virMutexLock(&state->lock);
+}
+
+void
+virObjectEventStateUnlock(virObjectEventStatePtr state)
+{
+    virMutexUnlock(&state->lock);
+}
+
+/**
+ * virObjectEventStateFree:
+ * @list: virObjectEventStatePtr to free
+ *
+ * Free a virObjectEventStatePtr and its members, and unregister the timer.
+ */
+void
+virObjectEventStateFree(virObjectEventStatePtr state)
+{
+    if (!state)
+        return;
+
+    virObjectEventCallbackListFree(state->callbacks);
+    virObjectEventQueueFree(state->queue);
+
+    if (state->timer != -1)
+        virEventRemoveTimeout(state->timer);
+
+    virMutexDestroy(&state->lock);
+    VIR_FREE(state);
+}
+
+
+static void virObjectEventStateFlush(virObjectEventStatePtr state);
+
+void
+virObjectEventTimer(int timer ATTRIBUTE_UNUSED, void *opaque)
+{
+    virObjectEventStatePtr state = opaque;
+
+    virObjectEventStateFlush(state);
+}
+
+/**
+ * virObjectEventStateNew:
+ */
+virObjectEventStatePtr
+virObjectEventStateNew(void)
+{
+    virObjectEventStatePtr state = NULL;
+
+    if (VIR_ALLOC(state) < 0)
+        goto error;
+
+    if (virMutexInit(&state->lock) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("unable to initialize state mutex"));
+        VIR_FREE(state);
+        goto error;
+    }
+
+    if (VIR_ALLOC(state->callbacks) < 0)
+        goto error;
+
+    if (!(state->queue = virObjectEventQueueNew()))
+        goto error;
+
+    state->timer = -1;
+
+    return state;
+
+error:
+    virObjectEventStateFree(state);
+    return NULL;
+}
+
+virObjectEventPtr virObjectEventNewInternal(int eventID,
+                                            int id,
+                                            const char *name,
+                                            const unsigned char *uuid)
+{
+    virObjectEventPtr event;
+
+    if (VIR_ALLOC(event) < 0)
+        return NULL;
+
+    event->eventID = eventID;
+    if (VIR_STRDUP(event->dom.name, name) < 0) {
+        VIR_FREE(event);
+        return NULL;
+    }
+    event->dom.id = id;
+    memcpy(event->dom.uuid, uuid, VIR_UUID_BUFLEN);
+
+    return event;
+}
+
+
+/**
+ * virObjectEventQueuePush:
+ * @evtQueue: the dom event queue
+ * @event: the event to add
+ *
+ * Internal function to push to the back of a virObjectEventQueue
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int
+virObjectEventQueuePush(virObjectEventQueuePtr evtQueue,
+                        virObjectEventPtr event)
+{
+    if (!evtQueue) {
+        return -1;
+    }
+
+    /* Make space on queue */
+    if (VIR_REALLOC_N(evtQueue->events,
+                      evtQueue->count + 1) < 0)
+        return -1;
+
+    evtQueue->events[evtQueue->count] = event;
+    evtQueue->count++;
+    return 0;
+}
+
+
+typedef void (*virObjectEventDispatchFunc)(virConnectPtr conn,
+                                           virObjectEventPtr event,
+                                           virConnectObjectEventGenericCallback cb,
+                                           void *cbopaque,
+                                           void *opaque);
+
+
+static void
+virDomainEventDispatchDefaultFunc(virConnectPtr conn,
+                                  virObjectEventPtr event,
+                                  virConnectDomainEventGenericCallback cb,
+                                  void *cbopaque,
+                                  void *opaque ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom = virGetDomain(conn, event->dom.name, event->dom.uuid);
+    if (!dom)
+        return;
+    dom->id = event->dom.id;
+
+    switch ((virDomainEventID) event->eventID) {
+    case VIR_DOMAIN_EVENT_ID_LIFECYCLE:
+        ((virConnectDomainEventCallback)cb)(conn, dom,
+                                            event->data.domainData.lifecycle.type,
+                                            event->data.domainData.lifecycle.detail,
+                                            cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_REBOOT:
+        (cb)(conn, dom,
+             cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_RTC_CHANGE:
+        ((virConnectDomainEventRTCChangeCallback)cb)(conn, dom,
+                                                     event->data.domainData.rtcChange.offset,
+                                                     cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_WATCHDOG:
+        ((virConnectDomainEventWatchdogCallback)cb)(conn, dom,
+                                                    event->data.domainData.watchdog.action,
+                                                    cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_IO_ERROR:
+        ((virConnectDomainEventIOErrorCallback)cb)(conn, dom,
+                                                   event->data.domainData.ioError.srcPath,
+                                                   event->data.domainData.ioError.devAlias,
+                                                   event->data.domainData.ioError.action,
+                                                   cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
+        ((virConnectDomainEventIOErrorReasonCallback)cb)(conn, dom,
+                                                         event->data.domainData.ioError.srcPath,
+                                                         event->data.domainData.ioError.devAlias,
+                                                         event->data.domainData.ioError.action,
+                                                         event->data.domainData.ioError.reason,
+                                                         cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_GRAPHICS:
+        ((virConnectDomainEventGraphicsCallback)cb)(conn, dom,
+                                                    event->data.domainData.graphics.phase,
+                                                    event->data.domainData.graphics.local,
+                                                    event->data.domainData.graphics.remote,
+                                                    event->data.domainData.graphics.authScheme,
+                                                    event->data.domainData.graphics.subject,
+                                                    cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
+        (cb)(conn, dom,
+             cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
+        ((virConnectDomainEventBlockJobCallback)cb)(conn, dom,
+                                                    event->data.domainData.blockJob.path,
+                                                    event->data.domainData.blockJob.type,
+                                                    event->data.domainData.blockJob.status,
+                                                    cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
+        ((virConnectDomainEventDiskChangeCallback)cb)(conn, dom,
+                                                      event->data.domainData.diskChange.oldSrcPath,
+                                                      event->data.domainData.diskChange.newSrcPath,
+                                                      event->data.domainData.diskChange.devAlias,
+                                                      event->data.domainData.diskChange.reason,
+                                                      cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
+        ((virConnectDomainEventTrayChangeCallback)cb)(conn, dom,
+                                                      event->data.domainData.trayChange.devAlias,
+                                                      event->data.domainData.trayChange.reason,
+                                                      cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_PMWAKEUP:
+        ((virConnectDomainEventPMWakeupCallback)cb)(conn, dom, 0, cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_PMSUSPEND:
+        ((virConnectDomainEventPMSuspendCallback)cb)(conn, dom, 0, cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
+        ((virConnectDomainEventBalloonChangeCallback)cb)(conn, dom,
+                                                         event->data.domainData.balloonChange.actual,
+                                                         cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
+        ((virConnectDomainEventPMSuspendDiskCallback)cb)(conn, dom, 0, cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
+        ((virConnectDomainEventDeviceRemovedCallback)cb)(conn, dom,
+                                                         event->data.domainData.deviceRemoved.devAlias,
+                                                         cbopaque);
+        goto cleanup;
+
+    case VIR_DOMAIN_EVENT_ID_LAST:
+        break;
+    }
+    VIR_WARN("Unexpected event ID %d", event->eventID);
+
+cleanup:
+    virDomainFree(dom);
+}
+
+
+static int virObjectEventDispatchMatchCallback(virObjectEventPtr event,
+                                               virObjectEventCallbackPtr cb)
+{
+    if (!cb)
+        return 0;
+    if (cb->deleted)
+        return 0;
+    if (cb->eventID != event->eventID)
+        return 0;
+
+    if (cb->dom) {
+        /* Deliberately ignoring 'id' for matching, since that
+         * will cause problems when a domain switches between
+         * running & shutoff states & ignoring 'name' since
+         * Xen sometimes renames guests during migration, thus
+         * leaving 'uuid' as the only truly reliable ID we can use*/
+
+        if (memcmp(event->dom.uuid, cb->dom->uuid, VIR_UUID_BUFLEN) == 0)
+            return 1;
+
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+
+static void
+virObjectEventDispatch(virObjectEventPtr event,
+                       virObjectEventCallbackListPtr callbacks,
+                       virObjectEventDispatchFunc dispatch,
+                       void *opaque)
+{
+    size_t i;
+    /* Cache this now, since we may be dropping the lock,
+       and have more callbacks added. We're guaranteed not
+       to have any removed */
+    int cbCount = callbacks->count;
+
+    for (i = 0; i < cbCount; i++) {
+        if (!virObjectEventDispatchMatchCallback(event, callbacks->callbacks[i]))
+            continue;
+
+        (*dispatch)(callbacks->callbacks[i]->conn,
+                    event,
+                    callbacks->callbacks[i]->cb,
+                    callbacks->callbacks[i]->opaque,
+                    opaque);
+    }
+}
+
+
+static void
+virObjectEventQueueDispatch(virObjectEventQueuePtr queue,
+                            virObjectEventCallbackListPtr callbacks,
+                            virObjectEventDispatchFunc dispatch,
+                            void *opaque)
+{
+    size_t i;
+
+    for (i = 0; i < queue->count; i++) {
+        virObjectEventDispatch(queue->events[i], callbacks, dispatch, opaque);
+        virObjectEventFree(queue->events[i]);
+    }
+    VIR_FREE(queue->events);
+    queue->count = 0;
+}
+
+void
+virObjectEventStateQueue(virObjectEventStatePtr state,
+                         virObjectEventPtr event)
+{
+    if (state->timer < 0) {
+        virObjectEventFree(event);
+        return;
+    }
+
+    virObjectEventStateLock(state);
+
+    if (virObjectEventQueuePush(state->queue, event) < 0) {
+        VIR_DEBUG("Error adding event to queue");
+        virObjectEventFree(event);
+    }
+
+    if (state->queue->count == 1)
+        virEventUpdateTimeout(state->timer, 0);
+    virObjectEventStateUnlock(state);
+}
+
+
+static void
+virObjectEventStateDispatchFunc(virConnectPtr conn,
+                                virObjectEventPtr event,
+                                virConnectObjectEventGenericCallback cb,
+                                void *cbopaque,
+                                void *opaque)
+{
+    virObjectEventStatePtr state = opaque;
+    virEventNamespaceID namespace = (event->eventID & 0xFF00) >> 8;
+
+    /* Drop the lock whle dispatching, for sake of re-entrancy */
+    virObjectEventStateUnlock(state);
+    switch (namespace)
+    {
+        case VIR_EVENT_NAMESPACE_DOMAIN:
+            virDomainEventDispatchDefaultFunc(conn, event,
+                    VIR_DOMAIN_EVENT_CALLBACK(cb), cbopaque, NULL);
+            break;
+    }
+    virObjectEventStateLock(state);
+}
+
+
+static void
+virObjectEventStateFlush(virObjectEventStatePtr state)
+{
+    virObjectEventQueue tempQueue;
+
+    virObjectEventStateLock(state);
+    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);
+
+    virObjectEventQueueDispatch(&tempQueue,
+                                state->callbacks,
+                                virObjectEventStateDispatchFunc,
+                                state);
+
+    /* Purge any deleted callbacks */
+    virObjectEventCallbackListPurgeMarked(state->callbacks);
+
+    state->isDispatching = false;
+    virObjectEventStateUnlock(state);
+}
+
+
+/**
+ * virObjectEventStateRegisterID:
+ * @conn: connection to associate with callback
+ * @state: domain event state
+ * @eventID: ID of the event type to register for
+ * @cb: function to remove from event
+ * @opaque: data blob to pass to callback
+ * @freecb: callback to free @opaque
+ * @callbackID: filled with callback ID
+ *
+ * Register the function @callbackID with connection @conn,
+ * from @state, for events of type @eventID.
+ *
+ * Returns: the number of callbacks now registered, or -1 on error
+ */
+int
+virObjectEventStateRegisterID(virConnectPtr conn,
+                              virObjectEventStatePtr state,
+                              unsigned char uuid[VIR_UUID_BUFLEN],
+                              const char *name,
+                              int id,
+                              int eventID,
+                              virConnectObjectEventGenericCallback cb,
+                              void *opaque,
+                              virFreeCallback freecb,
+                              int *callbackID)
+{
+    int ret = -1;
+
+    virObjectEventStateLock(state);
+
+    if ((state->callbacks->count == 0) &&
+        (state->timer == -1) &&
+        (state->timer = virEventAddTimeout(-1,
+                                           virObjectEventTimer,
+                                           state,
+                                           NULL)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("could not initialize domain event timer"));
+        goto cleanup;
+    }
+
+    ret = virObjectEventCallbackListAddID(conn, state->callbacks,
+                                          uuid, name, id, eventID, cb, opaque, freecb,
+                                          callbackID);
+
+    if (ret == -1 &&
+        state->callbacks->count == 0 &&
+        state->timer != -1) {
+        virEventRemoveTimeout(state->timer);
+        state->timer = -1;
+    }
+
+cleanup:
+    virObjectEventStateUnlock(state);
+    return ret;
+}
+
+
+/**
+ * virObjectEventStateDeregisterID:
+ * @conn: connection to associate with callback
+ * @state: domain event state
+ * @callbackID: ID of the function to remove from event
+ *
+ * Unregister the function @callbackID with connection @conn,
+ * from @state, for events.
+ *
+ * Returns: the number of callbacks still registered, or -1 on error
+ */
+int
+virObjectEventStateDeregisterID(virConnectPtr conn,
+                                virObjectEventStatePtr state,
+                                int callbackID)
+{
+    int ret;
+
+    virObjectEventStateLock(state);
+    if (state->isDispatching)
+        ret = virObjectEventCallbackListMarkDeleteID(conn,
+                                                     state->callbacks, callbackID);
+    else
+        ret = virObjectEventCallbackListRemoveID(conn,
+                                                 state->callbacks, callbackID);
+
+    if (state->callbacks->count == 0 &&
+        state->timer != -1) {
+        virEventRemoveTimeout(state->timer);
+        state->timer = -1;
+        virObjectEventQueueClear(state->queue);
+    }
+
+    virObjectEventStateUnlock(state);
+    return ret;
+}
+
+
+/**
+ * virObjectEventStateEventID:
+ * @conn: connection associated with the callback
+ * @state: domain event state
+ * @callbackID: the callback to query
+ *
+ * Query what event ID type is associated with the
+ * callback @callbackID for connection @conn
+ *
+ * Returns 0 on success, -1 on error
+ */
+int
+virObjectEventStateEventID(virConnectPtr conn,
+                           virObjectEventStatePtr state,
+                           int callbackID)
+{
+    int ret;
+
+    virObjectEventStateLock(state);
+    ret = virObjectEventCallbackListEventID(conn,
+                                            state->callbacks, callbackID);
+    virObjectEventStateUnlock(state);
+    return ret;
+}
diff --git a/src/conf/object_event.h b/src/conf/object_event.h
new file mode 100644
index 0000000..bf5727f
--- /dev/null
+++ b/src/conf/object_event.h
@@ -0,0 +1,93 @@
+/*
+ * domain_event.h: domain event queue processing helpers
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2008 VirtualIron
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ben Guthro
+ */
+
+#include "internal.h"
+
+#ifndef __OBJECT_EVENT_H__
+# define __OBJECT_EVENT_H__
+
+typedef struct _virObjectEventCallback virObjectEventCallback;
+typedef virObjectEventCallback *virObjectEventCallbackPtr;
+
+typedef struct _virObjectEventCallbackList virObjectEventCallbackList;
+typedef virObjectEventCallbackList *virObjectEventCallbackListPtr;
+
+/**
+ * Dispatching domain events that come in while
+ * in a call / response rpc
+ */
+typedef struct _virObjectEvent virObjectEvent;
+typedef virObjectEvent *virObjectEventPtr;
+
+typedef struct _virObjectEventQueue virObjectEventQueue;
+typedef virObjectEventQueue *virObjectEventQueuePtr;
+
+typedef struct _virObjectEventState virObjectEventState;
+typedef virObjectEventState *virObjectEventStatePtr;
+
+void virObjectEventFree(virObjectEventPtr event);
+
+void virObjectEventStateFree(virObjectEventStatePtr state);
+virObjectEventStatePtr
+virObjectEventStateNew(void);
+
+/*
+ * virConnectObjectEventGenericCallback:
+ * @conn: the connection pointer
+ * @obj: the object pointer
+ * @opaque: application specified data
+ *
+ * A generic object event callback handler. Specific events usually
+ * have a customization with extra parameters
+ */
+typedef void (*virConnectObjectEventGenericCallback)(virConnectPtr conn,
+                                                     void *obj,
+                                                     void *opaque);
+
+void
+virObjectEventStateQueue(virObjectEventStatePtr state,
+                         virObjectEventPtr event)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int virObjectEventStateRegisterID(virConnectPtr conn,
+                                  virObjectEventStatePtr state,
+                                  unsigned char uuid[VIR_UUID_BUFLEN],
+                                  const char *name,
+                                  int id,
+                                  int eventID,
+                                  virConnectObjectEventGenericCallback cb,
+                                  void *opaque,
+                                  virFreeCallback freecb,
+                                  int *callbackID)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(7);
+int
+virObjectEventStateDeregisterID(virConnectPtr conn,
+                                virObjectEventStatePtr state,
+                                int callbackID)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int
+virObjectEventStateEventID(virConnectPtr conn,
+                           virObjectEventStatePtr state,
+                           int callbackID)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+#endif
diff --git a/src/conf/object_event_private.h b/src/conf/object_event_private.h
new file mode 100644
index 0000000..8089155
--- /dev/null
+++ b/src/conf/object_event_private.h
@@ -0,0 +1,160 @@
+/*
+ * domain_event.h: domain event queue processing helpers
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2008 VirtualIron
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ben Guthro
+ */
+
+#ifndef __OBJECT_EVENT_PRIVATE_H__
+# define __OBJECT_EVENT_PRIVATE_H__
+
+#include "datatypes.h"
+
+#define VIR_OBJECT_EVENT_CALLBACK(cb) ((virConnectObjectEventGenericCallback)(cb))
+
+struct _virObjectMeta {
+    int id;
+    char *name;
+    unsigned char uuid[VIR_UUID_BUFLEN];
+};
+typedef struct _virObjectMeta virObjectMeta;
+typedef virObjectMeta *virObjectMetaPtr;
+
+struct _virObjectEventCallbackList {
+    unsigned int nextID;
+    unsigned int count;
+    virObjectEventCallbackPtr *callbacks;
+};
+
+struct _virObjectEventQueue {
+    unsigned int count;
+    virObjectEventPtr *events;
+};
+
+struct _virObjectEventState {
+    /* The list of domain event callbacks */
+    virObjectEventCallbackListPtr callbacks;
+    /* The queue of domain events */
+    virObjectEventQueuePtr queue;
+    /* Timer for flushing events queue */
+    int timer;
+    /* Flag if we're in process of dispatching */
+    bool isDispatching;
+    virMutex lock;
+};
+
+struct _virObjectEventCallback {
+    int callbackID;
+    int eventID;
+    virConnectPtr conn;
+    virObjectMetaPtr dom;
+    virConnectObjectEventGenericCallback cb;
+    void *opaque;
+    virFreeCallback freecb;
+    int deleted;
+};
+
+union virDomainEventData {
+    struct {
+        int type;
+        int detail;
+    } lifecycle;
+    struct {
+        long long offset;
+    } rtcChange;
+    struct {
+        int action;
+    } watchdog;
+    struct {
+        char *srcPath;
+        char *devAlias;
+        int action;
+        char *reason;
+    } ioError;
+    struct {
+        int phase;
+        virDomainEventGraphicsAddressPtr local;
+        virDomainEventGraphicsAddressPtr remote;
+        char *authScheme;
+        virDomainEventGraphicsSubjectPtr subject;
+    } graphics;
+    struct {
+        char *path;
+        int type;
+        int status;
+    } blockJob;
+    struct {
+        char *oldSrcPath;
+        char *newSrcPath;
+        char *devAlias;
+        int reason;
+    } diskChange;
+    struct {
+        char *devAlias;
+        int reason;
+    } trayChange;
+    struct {
+        /* In unit of 1024 bytes */
+        unsigned long long actual;
+    } balloonChange;
+    struct {
+        char *devAlias;
+    } deviceRemoved;
+};
+
+struct _virObjectEvent {
+    int eventID;
+
+    virObjectMeta dom;
+
+    union {
+        union virDomainEventData domainData;
+    } data;
+};
+
+virObjectEventPtr virObjectEventNewInternal(int eventID,
+                                            int id,
+                                            const char *name,
+                                            const unsigned char *uuid);
+
+int
+virObjectEventCallbackListAddID(virConnectPtr conn,
+                                virObjectEventCallbackListPtr cbList,
+                                unsigned char uuid[VIR_UUID_BUFLEN],
+                                const char *name,
+                                int id,
+                                int eventID,
+                                virConnectObjectEventGenericCallback callback,
+                                void *opaque,
+                                virFreeCallback freecb,
+                                int *callbackID);
+
+void
+virObjectEventStateLock(virObjectEventStatePtr state);
+
+void
+virObjectEventStateUnlock(virObjectEventStatePtr state);
+
+void
+virObjectEventTimer(int timer ATTRIBUTE_UNUSED, void *opaque);
+
+void
+virObjectEventQueueClear(virObjectEventQueuePtr queue);
+
+#endif
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a705c56..dc3882b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -421,7 +421,6 @@ virDomainEventDeviceRemovedNewFromDom;
 virDomainEventDeviceRemovedNewFromObj;
 virDomainEventDiskChangeNewFromDom;
 virDomainEventDiskChangeNewFromObj;
-virDomainEventFree;
 virDomainEventGraphicsNewFromDom;
 virDomainEventGraphicsNewFromObj;
 virDomainEventIOErrorNewFromDom;
@@ -444,11 +443,6 @@ virDomainEventRebootNewFromObj;
 virDomainEventRTCChangeNewFromDom;
 virDomainEventRTCChangeNewFromObj;
 virDomainEventStateDeregister;
-virDomainEventStateDeregisterID;
-virDomainEventStateEventID;
-virDomainEventStateFree;
-virDomainEventStateNew;
-virDomainEventStateQueue;
 virDomainEventStateRegister;
 virDomainEventStateRegisterID;
 virDomainEventTrayChangeNewFromDom;
@@ -625,6 +619,15 @@ virNWFilterVarValueGetCardinality;
 virNWFilterVarValueGetNthValue;
 virNWFilterVarValueGetSimple;
 
+# conf/object_event.h
+virObjectEventFree;
+virObjectEventStateDeregisterID;
+virObjectEventStateEventID;
+virObjectEventStateFree;
+virObjectEventStateNew;
+virObjectEventStateQueue;
+virObjectEventStateRegisterID;
+
 
 # conf/secret_conf.h
 virSecretDefFormat;
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 8ba0ee4..ffa93bd 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -105,7 +105,7 @@ struct _libxlDriverPrivate {
     virDomainXMLOptionPtr xmlopt;
 
     /* Immutable pointer, self-locking APIs */
-    virDomainEventStatePtr domainEventState;
+    virObjectEventStatePtr domainEventState;
 
     /* Immutable pointer, self-locking APIs */
     virPortAllocatorPtr reservedVNCPorts;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 7a75a04..8ead663 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -100,9 +100,9 @@ libxlDomObjFromDomain(virDomainPtr dom)
 }
 
 static void
-libxlDomainEventQueue(libxlDriverPrivatePtr driver, virDomainEventPtr event)
+libxlDomainEventQueue(libxlDriverPrivatePtr driver, virObjectEventPtr event)
 {
-    virDomainEventStateQueue(driver->domainEventState, event);
+    virObjectEventStateQueue(driver->domainEventState, event);
 }
 
 static int
@@ -359,7 +359,7 @@ libxlEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event)
     libxlDriverPrivatePtr driver = libxl_driver;
     libxlDomainObjPrivatePtr priv = ((virDomainObjPtr)data)->privateData;
     virDomainObjPtr vm = NULL;
-    virDomainEventPtr dom_event = NULL;
+    virObjectEventPtr dom_event = NULL;
     libxl_shutdown_reason xl_reason = event->u.domain_shutdown.shutdown_reason;
 
     if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
@@ -546,7 +546,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
 {
     libxl_domain_config d_config;
     virDomainDefPtr def = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     libxlSavefileHeader hdr;
     int ret;
     uint32_t domid = 0;
@@ -778,7 +778,7 @@ libxlStateCleanup(void)
     virObjectUnref(libxl_driver->domains);
     virObjectUnref(libxl_driver->reservedVNCPorts);
 
-    virDomainEventStateFree(libxl_driver->domainEventState);
+    virObjectEventStateFree(libxl_driver->domainEventState);
     virSysinfoDefFree(libxl_driver->hostsysinfo);
 
     virMutexDestroy(&libxl_driver->lock);
@@ -888,7 +888,7 @@ libxlStateInitialize(bool privileged,
     /* read the host sysinfo */
     libxl_driver->hostsysinfo = virSysinfoRead();
 
-    libxl_driver->domainEventState = virDomainEventStateNew();
+    libxl_driver->domainEventState = virObjectEventStateNew();
     if (!libxl_driver->domainEventState)
         goto error;
 
@@ -1298,7 +1298,7 @@ libxlDomainSuspend(virDomainPtr dom)
     libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
     virDomainObjPtr vm;
     libxlDomainObjPrivatePtr priv;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     if (!(vm = libxlDomObjFromDomain(dom)))
@@ -1350,7 +1350,7 @@ libxlDomainResume(virDomainPtr dom)
     libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
     virDomainObjPtr vm;
     libxlDomainObjPrivatePtr priv;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     if (!(vm = libxlDomObjFromDomain(dom)))
@@ -1485,7 +1485,7 @@ libxlDomainDestroyFlags(virDomainPtr dom,
     libxlDriverPrivatePtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     virCheckFlags(0, -1);
 
@@ -1773,7 +1773,7 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
 {
     libxlDomainObjPrivatePtr priv = vm->privateData;
     libxlSavefileHeader hdr;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     char *xml = NULL;
     uint32_t xml_len;
     int fd = -1;
@@ -1963,7 +1963,7 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags)
     libxlDriverPrivatePtr driver = dom->conn->privateData;
     libxlDomainObjPrivatePtr priv;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     bool paused = false;
     int ret = -1;
 
@@ -2665,7 +2665,7 @@ libxlDomainDefineXML(virConnectPtr conn, const char *xml)
     virDomainDefPtr def = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virDomainDefPtr oldDef = NULL;
 
     /* Lock the driver until the virDomainObj is created and locked */
@@ -2726,7 +2726,7 @@ libxlDomainUndefineFlags(virDomainPtr dom,
     libxlDriverPrivatePtr driver = dom->conn->privateData;
     libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver);
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     char *name = NULL;
     int ret = -1;
 
@@ -4145,7 +4145,7 @@ libxlConnectDomainEventDeregisterAny(virConnectPtr conn, int callbackID)
     if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
         return -1;
 
-    ret = virDomainEventStateDeregisterID(conn,
+    ret = virObjectEventStateDeregisterID(conn,
                                           driver->domainEventState,
                                           callbackID);
 
diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h
index a6208a2..f6cbfc9 100644
--- a/src/lxc/lxc_conf.h
+++ b/src/lxc/lxc_conf.h
@@ -97,7 +97,7 @@ struct _virLXCDriver {
     virUSBDeviceListPtr activeUsbHostdevs;
 
     /* Immutable pointer, self-locking APIs */
-    virDomainEventStatePtr domainEventState;
+    virObjectEventStatePtr domainEventState;
 
     /* Immutable pointer. self-locking APIs */
     virSecurityManagerPtr securityManager;
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 61a90ca..f65e7d6 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -441,7 +441,7 @@ static virDomainPtr lxcDomainDefineXML(virConnectPtr conn, const char *xml)
     virDomainDefPtr def = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virDomainDefPtr oldDef = NULL;
     virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
     virCapsPtr caps = NULL;
@@ -496,7 +496,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     if (event)
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
     virObjectUnref(caps);
     virObjectUnref(cfg);
     return dom;
@@ -507,7 +507,7 @@ static int lxcDomainUndefineFlags(virDomainPtr dom,
 {
     virLXCDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
 
@@ -547,7 +547,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     if (event)
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
     virObjectUnref(cfg);
     return ret;
 }
@@ -902,7 +902,7 @@ static int lxcDomainCreateWithFiles(virDomainPtr dom,
 {
     virLXCDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
 
@@ -944,7 +944,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     if (event)
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
     virObjectUnref(cfg);
     return ret;
 }
@@ -996,7 +996,7 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
     virDomainObjPtr vm = NULL;
     virDomainDefPtr def = NULL;
     virDomainPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
     virCapsPtr caps = NULL;
 
@@ -1054,7 +1054,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     if (event)
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
     virObjectUnref(caps);
     virObjectUnref(cfg);
     return dom;
@@ -1245,7 +1245,7 @@ lxcConnectDomainEventDeregisterAny(virConnectPtr conn,
     if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
         return -1;
 
-    ret = virDomainEventStateDeregisterID(conn,
+    ret = virObjectEventStateDeregisterID(conn,
                                           driver->domainEventState,
                                           callbackID);
 
@@ -1268,7 +1268,7 @@ lxcDomainDestroyFlags(virDomainPtr dom,
 {
     virLXCDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     virLXCDomainObjPrivatePtr priv;
 
@@ -1302,7 +1302,7 @@ cleanup:
     if (vm)
         virObjectUnlock(vm);
     if (event)
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
     return ret;
 }
 
@@ -1398,7 +1398,7 @@ static int lxcStateInitialize(bool privileged,
     if (!(lxc_driver->domains = virDomainObjListNew()))
         goto cleanup;
 
-    lxc_driver->domainEventState = virDomainEventStateNew();
+    lxc_driver->domainEventState = virObjectEventStateNew();
     if (!lxc_driver->domainEventState)
         goto cleanup;
 
@@ -1481,12 +1481,12 @@ static void lxcNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
     virLXCDriverPtr driver = opaque;
 
     if (newVM) {
-        virDomainEventPtr event =
+        virObjectEventPtr event =
             virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_DEFINED,
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED);
         if (event)
-            virDomainEventStateQueue(driver->domainEventState, event);
+            virObjectEventStateQueue(driver->domainEventState, event);
     }
 }
 
@@ -1528,7 +1528,7 @@ static int lxcStateCleanup(void)
 
     virNWFilterUnRegisterCallbackDriver(&lxcCallbackDriver);
     virObjectUnref(lxc_driver->domains);
-    virDomainEventStateFree(lxc_driver->domainEventState);
+    virObjectEventStateFree(lxc_driver->domainEventState);
 
     virObjectUnref(lxc_driver->closeCallbacks);
 
@@ -2337,7 +2337,7 @@ static int lxcDomainSuspend(virDomainPtr dom)
 {
     virLXCDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
 
@@ -2372,7 +2372,7 @@ static int lxcDomainSuspend(virDomainPtr dom)
 
 cleanup:
     if (event)
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(cfg);
@@ -2383,7 +2383,7 @@ static int lxcDomainResume(virDomainPtr dom)
 {
     virLXCDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     virLXCDomainObjPrivatePtr priv;
     virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
@@ -2422,7 +2422,7 @@ static int lxcDomainResume(virDomainPtr dom)
 
 cleanup:
     if (event)
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
     if (vm)
         virObjectUnlock(vm);
     virObjectUnref(cfg);
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index c51c4d5..db85863 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -62,7 +62,7 @@ lxcProcessAutoDestroy(virDomainObjPtr dom,
                       void *opaque)
 {
     virLXCDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virLXCDomainObjPrivatePtr priv;
 
     VIR_DEBUG("driver=%p dom=%s conn=%p", driver, dom->def->name, conn);
@@ -82,7 +82,7 @@ lxcProcessAutoDestroy(virDomainObjPtr dom,
     }
 
     if (event)
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
 
     return dom;
 }
@@ -490,7 +490,7 @@ static void virLXCProcessMonitorEOFNotify(virLXCMonitorPtr mon,
                                           virDomainObjPtr vm)
 {
     virLXCDriverPtr driver = lxc_driver;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virLXCDomainObjPrivatePtr priv;
 
     VIR_DEBUG("mon=%p vm=%p", mon, vm);
@@ -533,7 +533,7 @@ static void virLXCProcessMonitorEOFNotify(virLXCMonitorPtr mon,
     if (vm)
         virObjectUnlock(vm);
     if (event) {
-        virDomainEventStateQueue(driver->domainEventState, event);
+        virObjectEventStateQueue(driver->domainEventState, event);
     }
 }
 
@@ -1394,12 +1394,12 @@ virLXCProcessAutostartDomain(virDomainObjPtr vm,
                       vm->def->name,
                       err ? err->message : "");
         } else {
-            virDomainEventPtr event =
+            virObjectEventPtr event =
                 virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_STARTED,
                                          VIR_DOMAIN_EVENT_STARTED_BOOTED);
             if (event)
-                virDomainEventStateQueue(data->driver->domainEventState, event);
+                virObjectEventStateQueue(data->driver->domainEventState, event);
         }
     }
     virObjectUnlock(vm);
diff --git a/src/parallels/parallels_utils.h b/src/parallels/parallels_utils.h
index 12403ea..6215553 100644
--- a/src/parallels/parallels_utils.h
+++ b/src/parallels/parallels_utils.h
@@ -44,7 +44,7 @@ struct _parallelsConn {
     virNetworkObjList networks;
     virCapsPtr caps;
     virDomainXMLOptionPtr xmlopt;
-    virDomainEventStatePtr domainEventState;
+    virObjectEventStatePtr domainEventState;
 };
 
 typedef struct _parallelsConn parallelsConn;
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index f9ff7af..f26f7b9 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -207,7 +207,7 @@ struct _virQEMUDriver {
     virQEMUCapsCachePtr qemuCapsCache;
 
     /* Immutable pointer, self-locking APIs */
-    virDomainEventStatePtr domainEventState;
+    virObjectEventStatePtr domainEventState;
 
     /* Immutable pointer. self-locking APIs */
     virSecurityManagerPtr securityManager;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 81d0ba9..d4fd6d1 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -118,9 +118,9 @@ qemuDomainAsyncJobPhaseFromString(enum qemuDomainAsyncJob job,
 
 
 void qemuDomainEventQueue(virQEMUDriverPtr driver,
-                          virDomainEventPtr event)
+                          virObjectEventPtr event)
 {
-    virDomainEventStateQueue(driver->domainEventState, event);
+    virObjectEventStateQueue(driver->domainEventState, event);
 }
 
 
@@ -2114,7 +2114,7 @@ qemuDomainCheckRemoveOptionalDisk(virQEMUDriverPtr driver,
                                   virDomainDiskDefPtr disk)
 {
     char uuid[VIR_UUID_STRING_BUFLEN];
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virDomainDiskDefPtr del_disk = NULL;
 
     virUUIDFormat(vm->def->uuid, uuid);
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 77e0c20..6a92351 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -196,7 +196,7 @@ int qemuDomainAsyncJobPhaseFromString(enum qemuDomainAsyncJob job,
 void qemuDomainEventFlush(int timer, void *opaque);
 
 void qemuDomainEventQueue(virQEMUDriverPtr driver,
-                          virDomainEventPtr event);
+                          virObjectEventPtr event);
 
 int qemuDomainObjBeginJob(virQEMUDriverPtr driver,
                           virDomainObjPtr obj,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 378b542..6292cf2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -597,7 +597,7 @@ qemuStateInitialize(bool privileged,
         goto error;
 
     /* Init domain events */
-    qemu_driver->domainEventState = virDomainEventStateNew();
+    qemu_driver->domainEventState = virObjectEventStateNew();
     if (!qemu_driver->domainEventState)
         goto error;
 
@@ -878,7 +878,7 @@ static void qemuNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
     virQEMUDriverPtr driver = opaque;
 
     if (newVM) {
-        virDomainEventPtr event =
+        virObjectEventPtr event =
             virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_DEFINED,
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED);
@@ -1015,7 +1015,7 @@ qemuStateCleanup(void) {
     ebtablesContextFree(qemu_driver->ebtables);
 
     /* Free domain callback list */
-    virDomainEventStateFree(qemu_driver->domainEventState);
+    virObjectEventStateFree(qemu_driver->domainEventState);
 
     virLockManagerPluginUnref(qemu_driver->lockManager);
 
@@ -1566,8 +1566,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
     virDomainDefPtr def = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
-    virDomainEventPtr event = NULL;
-    virDomainEventPtr event2 = NULL;
+    virObjectEventPtr event = NULL;
+    virObjectEventPtr event2 = NULL;
     unsigned int start_flags = VIR_QEMU_PROCESS_START_COLD;
     virQEMUCapsPtr qemuCaps = NULL;
     virCapsPtr caps = NULL;
@@ -1668,7 +1668,7 @@ static int qemuDomainSuspend(virDomainPtr dom) {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     qemuDomainObjPrivatePtr priv;
     virDomainPausedReason reason;
     int eventDetail;
@@ -1749,7 +1749,7 @@ static int qemuDomainResume(virDomainPtr dom) {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int state;
     virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
@@ -2074,7 +2074,7 @@ qemuDomainDestroyFlags(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     qemuDomainObjPrivatePtr priv;
 
     virCheckFlags(VIR_DOMAIN_DESTROY_GRACEFUL, -1);
@@ -3037,7 +3037,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom,
     bool was_running = false;
     int ret = -1;
     int rc;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virCapsPtr caps;
 
@@ -3517,7 +3517,7 @@ static int qemuDomainCoreDump(virDomainPtr dom,
     qemuDomainObjPrivatePtr priv;
     bool resume = false, paused = false;
     int ret = -1;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH |
                   VIR_DUMP_BYPASS_CACHE | VIR_DUMP_RESET |
@@ -3822,7 +3822,7 @@ processGuestPanicEvent(virQEMUDriverPtr driver,
                        int action)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (!virDomainObjIsActive(vm)) {
@@ -5336,7 +5336,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
                            bool start_paused)
 {
     int ret = -1;
-    virDomainEventPtr event;
+    virObjectEventPtr event;
     int intermediatefd = -1;
     virCommandPtr cmd = NULL;
     char *errbuf = NULL;
@@ -6056,7 +6056,7 @@ qemuDomainObjStart(virConnectPtr conn,
                            VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags);
     virDomainAuditStart(vm, "booted", ret >= 0);
     if (ret >= 0) {
-        virDomainEventPtr event =
+        virObjectEventPtr event =
             virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_STARTED,
                                      VIR_DOMAIN_EVENT_STARTED_BOOTED);
@@ -6131,7 +6131,7 @@ static virDomainPtr qemuDomainDefineXML(virConnectPtr conn, const char *xml) {
     virDomainDefPtr oldDef = NULL;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virQEMUCapsPtr qemuCaps = NULL;
     virQEMUDriverConfigPtr cfg;
     virCapsPtr caps = NULL;
@@ -6224,7 +6224,7 @@ qemuDomainUndefineFlags(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     char *name = NULL;
     int ret = -1;
     int nsnapshots;
@@ -9949,7 +9949,7 @@ qemuConnectDomainEventDeregisterAny(virConnectPtr conn,
     if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
         goto cleanup;
 
-    if (virDomainEventStateDeregisterID(conn,
+    if (virObjectEventStateDeregisterID(conn,
                                         driver->domainEventState,
                                         callbackID) < 0)
         goto cleanup;
@@ -11661,7 +11661,7 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn,
 {
     virDomainObjPtr vm = *vmptr;
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     bool resume = false;
     int ret = -1;
 
@@ -12247,7 +12247,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
 
     /* the snapshot is complete now */
     if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT) {
-        virDomainEventPtr event;
+        virObjectEventPtr event;
 
         event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED,
                                          VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT);
@@ -12265,7 +12265,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
         /* qemu 1.3 is unable to save a domain in pm-suspended (S3)
          * state; so we must emit an event stating that it was
          * converted to paused.  */
-        virDomainEventPtr event;
+        virObjectEventPtr event;
 
         virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
                              VIR_DOMAIN_PAUSED_FROM_SNAPSHOT);
@@ -12282,7 +12282,7 @@ endjob:
         qemuProcessStartCPUs(driver, vm, conn,
                              VIR_DOMAIN_RUNNING_UNPAUSED,
                              QEMU_ASYNC_JOB_SNAPSHOT) < 0) {
-        virDomainEventPtr event = NULL;
+        virObjectEventPtr event = NULL;
         event = virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_SUSPENDED,
                                          VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR);
@@ -12942,8 +12942,8 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
     virDomainObjPtr vm = NULL;
     int ret = -1;
     virDomainSnapshotObjPtr snap = NULL;
-    virDomainEventPtr event = NULL;
-    virDomainEventPtr event2 = NULL;
+    virObjectEventPtr event = NULL;
+    virObjectEventPtr event2 = NULL;
     int detail;
     qemuDomainObjPrivatePtr priv;
     int rc;
@@ -13164,7 +13164,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
                                       QEMU_ASYNC_JOB_NONE);
             if (rc < 0)
                 goto endjob;
-            virDomainEventFree(event);
+            virObjectEventFree(event);
             event = NULL;
             if (was_stopped) {
                 /* Transition 2 */
@@ -13898,7 +13898,7 @@ cleanup:
         qemuProcessStartCPUs(driver, vm, conn,
                              VIR_DOMAIN_RUNNING_UNPAUSED,
                              QEMU_ASYNC_JOB_NONE) < 0) {
-        virDomainEventPtr event = NULL;
+        virObjectEventPtr event = NULL;
         event = virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_SUSPENDED,
                                          VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR);
@@ -13925,7 +13925,7 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
     char *device = NULL;
     int ret = -1;
     bool async = false;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int idx;
     virDomainDiskDefPtr disk;
 
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 0d9a3aa..84c2055 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2406,7 +2406,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
                            virDomainDiskDefPtr disk)
 {
     virDomainDeviceDef dev;
-    virDomainEventPtr event;
+    virObjectEventPtr event;
     size_t i;
 
     VIR_DEBUG("Removing disk %s from domain %p %s",
@@ -2450,7 +2450,7 @@ qemuDomainRemoveControllerDevice(virQEMUDriverPtr driver,
                                  virDomainObjPtr vm,
                                  virDomainControllerDefPtr controller)
 {
-    virDomainEventPtr event;
+    virObjectEventPtr event;
     size_t i;
 
     VIR_DEBUG("Removing controller %s from domain %p %s",
@@ -2538,7 +2538,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
 {
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     virDomainNetDefPtr net = NULL;
-    virDomainEventPtr event;
+    virObjectEventPtr event;
     size_t i;
 
     VIR_DEBUG("Removing host device %s from domain %p %s",
@@ -2609,7 +2609,7 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
 {
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     virNetDevVPortProfilePtr vport;
-    virDomainEventPtr event;
+    virObjectEventPtr event;
     size_t i;
 
     if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
@@ -2674,7 +2674,7 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
                           virDomainObjPtr vm,
                           virDomainChrDefPtr chr)
 {
-    virDomainEventPtr event;
+    virObjectEventPtr event;
 
     VIR_DEBUG("Removing character device %s from domain %p %s",
               chr->info.alias, vm, vm->def->name);
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index e87ea85..b998667 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1511,7 +1511,7 @@ qemuMigrationSetOffline(virQEMUDriverPtr driver,
     ret = qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_MIGRATION,
                               QEMU_ASYNC_JOB_MIGRATION_OUT);
     if (ret == 0) {
-        virDomainEventPtr event;
+        virObjectEventPtr event;
 
         event = virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_SUSPENDED,
@@ -2169,7 +2169,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
                         unsigned long flags)
 {
     virDomainObjPtr vm = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     int dataFD[2] = { -1, -1 };
     qemuDomainObjPrivatePtr priv = NULL;
@@ -2708,7 +2708,7 @@ qemuMigrationConfirmPhase(virQEMUDriverPtr driver,
                           int retcode)
 {
     qemuMigrationCookiePtr mig;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int rv = -1;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
@@ -4061,7 +4061,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver,
                         unsigned long resource,
                         bool v3proto)
 {
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     int resume = 0;
     virErrorPtr orig_err = NULL;
@@ -4175,7 +4175,7 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver,
                           unsigned long flags,
                           unsigned long resource)
 {
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     bool resume;
     bool hasrefs;
@@ -4371,7 +4371,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
                     bool v3proto)
 {
     virDomainPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     bool newVM = true;
     qemuMigrationCookiePtr mig = NULL;
     virErrorPtr orig_err = NULL;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a26c079..e9b1246 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -286,7 +286,7 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                             void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     qemuDomainObjPrivatePtr priv;
     int eventReason = VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN;
     int stopReason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
@@ -348,7 +348,7 @@ qemuProcessHandleMonitorError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     VIR_DEBUG("Received error on %p '%s'", vm, vm->def->name);
 
@@ -516,7 +516,7 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                        void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event;
+    virObjectEventPtr event;
     qemuDomainObjPrivatePtr priv;
 
     virObjectLock(vm);
@@ -549,7 +549,7 @@ qemuProcessFakeReboot(void *opaque)
     virQEMUDriverPtr driver = qemu_driver;
     virDomainObjPtr vm = opaque;
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED;
     int ret = -1;
@@ -648,7 +648,7 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 {
     virQEMUDriverPtr driver = opaque;
     qemuDomainObjPrivatePtr priv;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     VIR_DEBUG("vm=%p", vm);
@@ -702,7 +702,7 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                       void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
@@ -749,7 +749,7 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                         void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
@@ -803,7 +803,7 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                            void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
@@ -844,8 +844,8 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                           void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr watchdogEvent = NULL;
-    virDomainEventPtr lifecycleEvent = NULL;
+    virObjectEventPtr watchdogEvent = NULL;
+    virObjectEventPtr lifecycleEvent = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
@@ -911,9 +911,9 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                          void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr ioErrorEvent = NULL;
-    virDomainEventPtr ioErrorEvent2 = NULL;
-    virDomainEventPtr lifecycleEvent = NULL;
+    virObjectEventPtr ioErrorEvent = NULL;
+    virObjectEventPtr ioErrorEvent2 = NULL;
+    virObjectEventPtr lifecycleEvent = NULL;
     const char *srcPath;
     const char *devAlias;
     virDomainDiskDefPtr disk;
@@ -972,7 +972,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                           void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     const char *path;
     virDomainDiskDefPtr disk;
 
@@ -1025,7 +1025,7 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                           void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event;
+    virObjectEventPtr event;
     virDomainEventGraphicsAddressPtr localAddr = NULL;
     virDomainEventGraphicsAddressPtr remoteAddr = NULL;
     virDomainEventGraphicsSubjectPtr subject = NULL;
@@ -1104,7 +1104,7 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                             void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virDomainDiskDefPtr disk;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
@@ -1140,8 +1140,8 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                           void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
-    virDomainEventPtr lifecycleEvent = NULL;
+    virObjectEventPtr event = NULL;
+    virObjectEventPtr lifecycleEvent = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
@@ -1181,8 +1181,8 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                            void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
-    virDomainEventPtr lifecycleEvent = NULL;
+    virObjectEventPtr event = NULL;
+    virObjectEventPtr lifecycleEvent = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
@@ -1226,7 +1226,7 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
@@ -1253,8 +1253,8 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                void *opaque)
 {
     virQEMUDriverPtr driver = opaque;
-    virDomainEventPtr event = NULL;
-    virDomainEventPtr lifecycleEvent = NULL;
+    virObjectEventPtr event = NULL;
+    virObjectEventPtr lifecycleEvent = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     virObjectLock(vm);
@@ -4628,7 +4628,7 @@ qemuProcessAutoDestroy(virDomainObjPtr dom,
 {
     virQEMUDriverPtr driver = opaque;
     qemuDomainObjPrivatePtr priv = dom->privateData;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     VIR_DEBUG("vm=%s, conn=%p", dom->def->name, conn);
 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 7181949..0074f46 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -92,7 +92,7 @@ struct private_data {
     char *hostname;             /* Original hostname */
     bool serverKeepAlive;       /* Does server support keepalive protocol? */
 
-    virDomainEventStatePtr domainEventState;
+    virObjectEventStatePtr domainEventState;
 };
 
 enum {
@@ -150,7 +150,7 @@ static void make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virSto
 static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
 static void make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src);
 static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
-static void remoteDomainEventQueue(struct private_data *priv, virDomainEventPtr event);
+static void remoteDomainEventQueue(struct private_data *priv, virObjectEventPtr event);
 /*----------------------------------------------------------------------*/
 
 /* Helper functions for remoteOpen. */
@@ -880,7 +880,7 @@ doRemoteOpen(virConnectPtr conn,
             goto failed;
     }
 
-    if (!(priv->domainEventState = virDomainEventStateNew()))
+    if (!(priv->domainEventState = virObjectEventStateNew()))
         goto failed;
 
     /* Successful. */
@@ -1081,7 +1081,7 @@ doRemoteClose(virConnectPtr conn, struct private_data *priv)
     /* See comment for remoteType. */
     VIR_FREE(priv->type);
 
-    virDomainEventStateFree(priv->domainEventState);
+    virObjectEventStateFree(priv->domainEventState);
     priv->domainEventState = NULL;
 
     return ret;
@@ -4369,7 +4369,7 @@ remoteDomainBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_lifecycle_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4391,7 +4391,7 @@ remoteDomainBuildEventReboot(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_reboot_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4413,7 +4413,7 @@ remoteDomainBuildEventRTCChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_rtc_change_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4435,7 +4435,7 @@ remoteDomainBuildEventWatchdog(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_watchdog_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4457,7 +4457,7 @@ remoteDomainBuildEventIOError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_io_error_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4482,7 +4482,7 @@ remoteDomainBuildEventIOErrorReason(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
     struct private_data *priv = conn->privateData;
     remote_domain_event_io_error_reason_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn,msg->dom);
     if (!dom)
@@ -4508,7 +4508,7 @@ remoteDomainBuildEventBlockJob(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_block_job_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4531,7 +4531,7 @@ remoteDomainBuildEventGraphics(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_graphics_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virDomainEventGraphicsAddressPtr localAddr = NULL;
     virDomainEventGraphicsAddressPtr remoteAddr = NULL;
     virDomainEventGraphicsSubjectPtr subject = NULL;
@@ -4611,7 +4611,7 @@ remoteDomainBuildEventControlError(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_control_error_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4634,7 +4634,7 @@ remoteDomainBuildEventDiskChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_disk_change_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4661,7 +4661,7 @@ remoteDomainBuildEventTrayChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_tray_change_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4685,7 +4685,7 @@ remoteDomainBuildEventPMWakeup(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_pmwakeup_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4707,7 +4707,7 @@ remoteDomainBuildEventPMSuspend(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
     struct private_data *priv = conn->privateData;
     remote_domain_event_pmsuspend_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4730,7 +4730,7 @@ remoteDomainBuildEventBalloonChange(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
     struct private_data *priv = conn->privateData;
     remote_domain_event_balloon_change_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4752,7 +4752,7 @@ remoteDomainBuildEventPMSuspendDisk(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
     struct private_data *priv = conn->privateData;
     remote_domain_event_pmsuspend_disk_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -4775,7 +4775,7 @@ remoteDomainBuildEventDeviceRemoved(virNetClientProgramPtr prog ATTRIBUTE_UNUSED
     struct private_data *priv = conn->privateData;
     remote_domain_event_device_removed_msg *msg = evdata;
     virDomainPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     dom = get_nonnull_domain(conn, msg->dom);
     if (!dom)
@@ -5111,7 +5111,7 @@ static int remoteConnectDomainEventRegisterAny(virConnectPtr conn,
         if (call(conn, priv, 0, REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY,
                  (xdrproc_t) xdr_remote_connect_domain_event_register_any_args, (char *) &args,
                  (xdrproc_t) xdr_void, (char *)NULL) == -1) {
-            virDomainEventStateDeregisterID(conn,
+            virObjectEventStateDeregisterID(conn,
                                             priv->domainEventState,
                                             callbackID);
             goto done;
@@ -5137,14 +5137,14 @@ static int remoteConnectDomainEventDeregisterAny(virConnectPtr conn,
 
     remoteDriverLock(priv);
 
-    if ((eventID = virDomainEventStateEventID(conn,
+    if ((eventID = virObjectEventStateEventID(conn,
                                               priv->domainEventState,
                                               callbackID)) < 0) {
         virReportError(VIR_ERR_RPC, _("unable to find callback ID %d"), callbackID);
         goto done;
     }
 
-    if ((count = virDomainEventStateDeregisterID(conn,
+    if ((count = virObjectEventStateDeregisterID(conn,
                                                  priv->domainEventState,
                                                  callbackID)) < 0) {
         virReportError(VIR_ERR_RPC, _("unable to find callback ID %d"), callbackID);
@@ -6679,9 +6679,9 @@ done:
 }
 
 static void
-remoteDomainEventQueue(struct private_data *priv, virDomainEventPtr event)
+remoteDomainEventQueue(struct private_data *priv, virObjectEventPtr event)
 {
-    virDomainEventStateQueue(priv->domainEventState, event);
+    virObjectEventStateQueue(priv->domainEventState, event);
 }
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 2678247..f472494 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -99,7 +99,7 @@ struct _testConn {
     int numCells;
     testCell cells[MAX_CELLS];
 
-    virDomainEventStatePtr domainEventState;
+    virObjectEventStatePtr domainEventState;
 };
 typedef struct _testConn testConn;
 typedef struct _testConn *testConnPtr;
@@ -122,7 +122,7 @@ static const virNodeInfo defaultNodeInfo = {
 
 static int testConnectClose(virConnectPtr conn);
 static void testDomainEventQueue(testConnPtr driver,
-                                 virDomainEventPtr event);
+                                 virObjectEventPtr event);
 
 
 static void testDriverLock(testConnPtr driver)
@@ -1444,7 +1444,7 @@ static virDrvOpenStatus testConnectOpen(virConnectPtr conn,
     privconn = conn->privateData;
     testDriverLock(privconn);
 
-    privconn->domainEventState = virDomainEventStateNew();
+    privconn->domainEventState = virObjectEventStateNew();
     if (!privconn->domainEventState) {
         testDriverUnlock(privconn);
         testConnectClose(conn);
@@ -1467,7 +1467,7 @@ static int testConnectClose(virConnectPtr conn)
     virNetworkObjListFree(&privconn->networks);
     virInterfaceObjListFree(&privconn->ifaces);
     virStoragePoolObjListFree(&privconn->pools);
-    virDomainEventStateFree(privconn->domainEventState);
+    virObjectEventStateFree(privconn->domainEventState);
     VIR_FREE(privconn->path);
 
     testDriverUnlock(privconn);
@@ -1615,7 +1615,7 @@ testDomainCreateXML(virConnectPtr conn, const char *xml,
     virDomainPtr ret = NULL;
     virDomainDefPtr def;
     virDomainObjPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     virCheckFlags(0, NULL);
 
@@ -1753,7 +1753,7 @@ static int testDomainDestroy(virDomainPtr domain)
 {
     testConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     testDriverLock(privconn);
@@ -1790,7 +1790,7 @@ static int testDomainResume(virDomainPtr domain)
 {
     testConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     testDriverLock(privconn);
@@ -1831,7 +1831,7 @@ static int testDomainSuspend(virDomainPtr domain)
 {
     testConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
     int state;
 
@@ -1875,7 +1875,7 @@ static int testDomainShutdownFlags(virDomainPtr domain,
 {
     testConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -1927,7 +1927,7 @@ static int testDomainReboot(virDomainPtr domain,
 {
     testConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     testDriverLock(privconn);
@@ -2071,7 +2071,7 @@ testDomainSaveFlags(virDomainPtr domain, const char *path,
     int fd = -1;
     int len;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -2184,7 +2184,7 @@ testDomainRestoreFlags(virConnectPtr conn,
     int len;
     virDomainDefPtr def = NULL;
     virDomainObjPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -2284,7 +2284,7 @@ static int testDomainCoreDump(virDomainPtr domain,
     testConnPtr privconn = domain->conn->privateData;
     int fd = -1;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     virCheckFlags(VIR_DUMP_CRASH, -1);
@@ -2783,7 +2783,7 @@ static virDomainPtr testDomainDefineXML(virConnectPtr conn,
     virDomainPtr ret = NULL;
     virDomainDefPtr def;
     virDomainObjPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     virDomainDefPtr oldDef = NULL;
 
     testDriverLock(privconn);
@@ -2921,7 +2921,7 @@ cleanup:
 static int testDomainCreateWithFlags(virDomainPtr domain, unsigned int flags) {
     testConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -2969,7 +2969,7 @@ static int testDomainUndefineFlags(virDomainPtr domain,
 {
     testConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr privdom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int nsnapshots;
     int ret = -1;
 
@@ -6018,7 +6018,7 @@ testConnectDomainEventDeregisterAny(virConnectPtr conn,
     int ret;
 
     testDriverLock(driver);
-    ret = virDomainEventStateDeregisterID(conn,
+    ret = virObjectEventStateDeregisterID(conn,
                                           driver->domainEventState,
                                           callbackID);
     testDriverUnlock(driver);
@@ -6029,9 +6029,9 @@ testConnectDomainEventDeregisterAny(virConnectPtr conn,
 
 /* driver must be locked before calling */
 static void testDomainEventQueue(testConnPtr driver,
-                                 virDomainEventPtr event)
+                                 virObjectEventPtr event)
 {
-    virDomainEventStateQueue(driver->domainEventState, event);
+    virObjectEventStateQueue(driver->domainEventState, event);
 }
 
 static virDrvOpenStatus testSecretOpen(virConnectPtr conn,
@@ -6151,7 +6151,7 @@ testDomainManagedSave(virDomainPtr dom, unsigned int flags)
 {
     testConnPtr privconn = dom->conn->privateData;
     virDomainObjPtr vm = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
@@ -6641,7 +6641,7 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
     virDomainSnapshotDefPtr def = NULL;
     virDomainSnapshotObjPtr snap = NULL;
     virDomainSnapshotPtr snapshot = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     char *xml = NULL;
     bool update_current = true;
     bool redefine = flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE;
@@ -6890,8 +6890,8 @@ testDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
     testConnPtr privconn = snapshot->domain->conn->privateData;
     virDomainObjPtr vm = NULL;
     virDomainSnapshotObjPtr snap = NULL;
-    virDomainEventPtr event = NULL;
-    virDomainEventPtr event2 = NULL;
+    virObjectEventPtr event = NULL;
+    virObjectEventPtr event2 = NULL;
     virDomainDefPtr config = NULL;
     int ret = -1;
 
@@ -7035,7 +7035,7 @@ testDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
             } /* else transition 6 and 9 use event as-is */
         } else {
             /* Transitions 2, 5, 8 */
-            virDomainEventFree(event);
+            virObjectEventFree(event);
             event = NULL;
 
             if (was_stopped) {
@@ -7089,7 +7089,7 @@ cleanup:
         if (event2)
             testDomainEventQueue(privconn, event2);
     } else {
-        virDomainEventFree(event2);
+        virObjectEventFree(event2);
     }
     virObjectUnlock(vm);
     testDriverUnlock(privconn);
diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h
index 7f7ea05..c23a177 100644
--- a/src/uml/uml_conf.h
+++ b/src/uml/uml_conf.h
@@ -66,7 +66,7 @@ struct uml_driver {
     virDomainXMLOptionPtr xmlopt;
 
     /* Event handling */
-    virDomainEventStatePtr domainEventState;
+    virObjectEventStatePtr domainEventState;
 
     /* Mapping of 'char *uuidstr' -> virConnectPtr
      * of guests which will be automatically killed
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 9ac896a..382a670 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -128,7 +128,7 @@ static int umlOpenMonitor(struct uml_driver *driver,
 static int umlReadPidFile(struct uml_driver *driver,
                           virDomainObjPtr vm);
 static void umlDomainEventQueue(struct uml_driver *driver,
-                                virDomainEventPtr event);
+                                virObjectEventPtr event);
 
 static int umlStartVMDaemon(virConnectPtr conn,
                             struct uml_driver *driver,
@@ -194,7 +194,7 @@ umlAutostartDomain(virDomainObjPtr vm,
             VIR_ERROR(_("Failed to autostart VM '%s': %s"),
                       vm->def->name, err ? err->message : _("unknown error"));
         } else {
-            virDomainEventPtr event =
+            virObjectEventPtr event =
                 virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_STARTED,
                                          VIR_DOMAIN_EVENT_STARTED_BOOTED);
@@ -301,7 +301,7 @@ umlInotifyEvent(int watch,
     char *tmp, *name;
     struct uml_driver *driver = data;
     virDomainObjPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     umlDriverLock(driver);
     if (watch != driver->inotifyWatch)
@@ -475,7 +475,7 @@ umlStateInitialize(bool privileged,
     if (!(uml_driver->domains = virDomainObjListNew()))
         goto error;
 
-    uml_driver->domainEventState = virDomainEventStateNew();
+    uml_driver->domainEventState = virObjectEventStateNew();
     if (!uml_driver->domainEventState)
         goto error;
 
@@ -604,7 +604,7 @@ static void umlNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque)
     struct uml_driver *driver = opaque;
 
     if (newVM) {
-        virDomainEventPtr event =
+        virObjectEventPtr event =
             virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_DEFINED,
                                      VIR_DOMAIN_EVENT_DEFINED_ADDED);
@@ -677,7 +677,7 @@ umlStateCleanup(void) {
 
     virObjectUnref(uml_driver->domains);
 
-    virDomainEventStateFree(uml_driver->domainEventState);
+    virObjectEventStateFree(uml_driver->domainEventState);
 
     VIR_FREE(uml_driver->logDir);
     VIR_FREE(uml_driver->configDir);
@@ -716,7 +716,7 @@ static void umlProcessAutoDestroyDom(void *payload,
     const char *uuidstr = name;
     unsigned char uuid[VIR_UUID_BUFLEN];
     virDomainObjPtr dom;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     VIR_DEBUG("conn=%p uuidstr=%s thisconn=%p", conn, uuidstr, data->conn);
 
@@ -1571,7 +1571,7 @@ static virDomainPtr umlDomainCreateXML(virConnectPtr conn, const char *xml,
     virDomainDefPtr def;
     virDomainObjPtr vm = NULL;
     virDomainPtr dom = NULL;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
 
     virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, NULL);
 
@@ -1667,7 +1667,7 @@ umlDomainDestroyFlags(virDomainPtr dom,
 {
     struct uml_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -1993,7 +1993,7 @@ static int umlConnectNumOfDefinedDomains(virConnectPtr conn) {
 static int umlDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) {
     struct uml_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    virDomainEventPtr event = NULL;
+    virObjectEventPtr event = NULL;
     int ret = -1;
 
     virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1);
@@ -2680,7 +2680,7 @@ umlConnectDomainEventDeregisterAny(virConnectPtr conn,
         return -1;
 
     umlDriverLock(driver);
-    ret = virDomainEventStateDeregisterID(conn,
+    ret = virObjectEventStateDeregisterID(conn,
                                           driver->domainEventState,
                                           callbackID);
     umlDriverUnlock(driver);
@@ -2691,9 +2691,9 @@ umlConnectDomainEventDeregisterAny(virConnectPtr conn,
 
 /* driver must be locked before calling */
 static void umlDomainEventQueue(struct uml_driver *driver,
-                                virDomainEventPtr event)
+                                virObjectEventPtr event)
 {
-    virDomainEventStateQueue(driver->domainEventState, event);
+    virObjectEventStateQueue(driver->domainEventState, event);
 }
 
 static int umlConnectListAllDomains(virConnectPtr conn,
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 3807a6d..b7c63b3 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -211,7 +211,7 @@ typedef struct {
 #else /* !(VBOX_API_VERSION == 2002) */
 
     /* Async event handling */
-    virDomainEventStatePtr domainEvents;
+    virObjectEventStatePtr domainEvents;
     int fdWatch;
 
 # if VBOX_API_VERSION <= 3002
@@ -988,7 +988,7 @@ static void vboxUninitialize(vboxGlobalData *data) {
 #if VBOX_API_VERSION == 2002
     /* No domainEventCallbacks in 2.2.* version */
 #else  /* !(VBOX_API_VERSION == 2002) */
-    virDomainEventStateFree(data->domainEvents);
+    virObjectEventStateFree(data->domainEvents);
 #endif /* !(VBOX_API_VERSION == 2002) */
     VIR_FREE(data);
 }
@@ -1053,7 +1053,7 @@ static virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
 
 #else  /* !(VBOX_API_VERSION == 2002) */
 
-    if (!(data->domainEvents = virDomainEventStateNew())) {
+    if (!(data->domainEvents = virObjectEventStateNew())) {
         vboxUninitialize(data);
         return VIR_DRV_OPEN_ERROR;
     }
@@ -6878,7 +6878,7 @@ vboxCallbackOnMachineStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
 
         dom = vboxDomainLookupByUUID(g_pVBoxGlobalData->conn, uuid);
         if (dom) {
-            virDomainEventPtr ev;
+            virObjectEventPtr ev;
 
             if (state == MachineState_Starting) {
                 event  = VIR_DOMAIN_EVENT_STARTED;
@@ -6912,7 +6912,7 @@ vboxCallbackOnMachineStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
             ev = virDomainEventNewFromDom(dom, event, detail);
 
             if (ev)
-                virDomainEventStateQueue(g_pVBoxGlobalData->domainEvents, ev);
+                virObjectEventStateQueue(g_pVBoxGlobalData->domainEvents, ev);
         }
     }
 
@@ -6997,7 +6997,7 @@ vboxCallbackOnMachineRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
 
         dom = vboxDomainLookupByUUID(g_pVBoxGlobalData->conn, uuid);
         if (dom) {
-            virDomainEventPtr ev;
+            virObjectEventPtr ev;
 
             /* CURRENT LIMITATION: we never get the VIR_DOMAIN_EVENT_UNDEFINED
              * event because the when the machine is de-registered the call
@@ -7016,7 +7016,7 @@ vboxCallbackOnMachineRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
             ev = virDomainEventNewFromDom(dom, event, detail);
 
             if (ev)
-                virDomainEventStateQueue(g_pVBoxGlobalData->domainEvents, ev);
+                virObjectEventStateQueue(g_pVBoxGlobalData->domainEvents, ev);
         }
     }
 
@@ -7241,7 +7241,7 @@ static int vboxConnectDomainEventRegister(virConnectPtr conn,
 
             ret = virDomainEventStateRegister(conn, data->domainEvents,
                                               callback, opaque, freecb);
-            VIR_DEBUG("virDomainEventStateRegister (ret = %d) (conn: %p, "
+            VIR_DEBUG("virObjectEventStateRegister (ret = %d) (conn: %p, "
                       "callback: %p, opaque: %p, "
                       "freecb: %p)", ret, conn, callback,
                       opaque, freecb);
@@ -7335,7 +7335,7 @@ static int vboxConnectDomainEventRegisterAny(virConnectPtr conn,
                                               dom, eventID,
                                               callback, opaque, freecb, &ret) < 0)
                 ret = -1;
-            VIR_DEBUG("virDomainEventStateRegisterID (ret = %d) (conn: %p, "
+            VIR_DEBUG("virObjectEventStateRegisterID (ret = %d) (conn: %p, "
                       "callback: %p, opaque: %p, "
                       "freecb: %p)", ret, conn, callback,
                       opaque, freecb);
@@ -7364,7 +7364,7 @@ static int vboxConnectDomainEventDeregisterAny(virConnectPtr conn,
      */
     vboxDriverLock(data);
 
-    cnt = virDomainEventStateDeregisterID(conn, data->domainEvents,
+    cnt = virObjectEventStateDeregisterID(conn, data->domainEvents,
                                           callbackID);
 
     if (data->vboxCallback && cnt == 0) {
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 9ba1b10..4103dc9 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -453,7 +453,7 @@ xenUnifiedConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int f
         return VIR_DRV_OPEN_ERROR;
     }
 
-    if (!(priv->domainEvents = virDomainEventStateNew())) {
+    if (!(priv->domainEvents = virObjectEventStateNew())) {
         virMutexDestroy(&priv->lock);
         VIR_FREE(priv);
         return VIR_DRV_OPEN_ERROR;
@@ -551,7 +551,7 @@ xenUnifiedConnectClose(virConnectPtr conn)
 
     virObjectUnref(priv->caps);
     virObjectUnref(priv->xmlopt);
-    virDomainEventStateFree(priv->domainEvents);
+    virObjectEventStateFree(priv->domainEvents);
 
 #if WITH_XEN_INOTIFY
     if (priv->opened[XEN_UNIFIED_INOTIFY_OFFSET])
@@ -2409,7 +2409,7 @@ xenUnifiedConnectDomainEventDeregisterAny(virConnectPtr conn,
         return -1;
     }
 
-    ret = virDomainEventStateDeregisterID(conn,
+    ret = virObjectEventStateDeregisterID(conn,
                                           priv->domainEvents,
                                           callbackID);
 
@@ -2946,12 +2946,12 @@ xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr list,
  *
  */
 void xenUnifiedDomainEventDispatch(xenUnifiedPrivatePtr priv,
-                                    virDomainEventPtr event)
+                                    virObjectEventPtr event)
 {
     if (!priv)
         return;
 
-    virDomainEventStateQueue(priv->domainEvents, event);
+    virObjectEventStateQueue(priv->domainEvents, event);
 }
 
 void xenUnifiedLock(xenUnifiedPrivatePtr priv)
diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
index a363161..b8c1c27 100644
--- a/src/xen/xen_driver.h
+++ b/src/xen/xen_driver.h
@@ -159,7 +159,7 @@ struct _xenUnifiedPrivate {
     int nbNodeCells;
     int nbNodeCpus;
 
-    virDomainEventStatePtr domainEvents;
+    virObjectEventStatePtr domainEvents;
 
     /* Location of config files, either /etc
      * or /var/lib/xen */
@@ -199,7 +199,7 @@ int  xenUnifiedRemoveDomainInfo(xenUnifiedDomainInfoListPtr info,
                                 int id, char *name,
                                 unsigned char *uuid);
 void xenUnifiedDomainEventDispatch (xenUnifiedPrivatePtr priv,
-                                    virDomainEventPtr event);
+                                    virObjectEventPtr event);
 unsigned long xenUnifiedVersion(void);
 int xenUnifiedConnectGetMaxVcpus(virConnectPtr conn, const char *type);
 
diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c
index 755be8f..b67178e 100644
--- a/src/xen/xen_inotify.c
+++ b/src/xen/xen_inotify.c
@@ -135,13 +135,13 @@ xenInotifyDomainLookup(virConnectPtr conn,
         return xenInotifyXendDomainsDirLookup(conn, filename, name, uuid);
 }
 
-static virDomainEventPtr
+static virObjectEventPtr
 xenInotifyDomainEventFromFile(virConnectPtr conn,
                               const char *filename,
                               int type,
                               int detail)
 {
-    virDomainEventPtr event;
+    virObjectEventPtr event;
     char *name = NULL;
     unsigned char uuid[VIR_UUID_BUFLEN];
 
@@ -290,7 +290,7 @@ reread:
                  priv->configDir, name);
 
         if (e->mask & (IN_DELETE | IN_MOVED_FROM)) {
-            virDomainEventPtr event =
+            virObjectEventPtr event =
                 xenInotifyDomainEventFromFile(conn, fname,
                                               VIR_DOMAIN_EVENT_UNDEFINED,
                                               VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
@@ -306,7 +306,7 @@ reread:
                 goto cleanup;
             }
         } else if (e->mask & (IN_CREATE | IN_CLOSE_WRITE | IN_MOVED_TO)) {
-            virDomainEventPtr event;
+            virObjectEventPtr event;
             if (xenInotifyAddDomainConfigInfo(conn, fname) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                "%s", _("Error adding file to config cache"));
diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c
index 4368f85..e66b6ad 100644
--- a/src/xen/xs_internal.c
+++ b/src/xen/xs_internal.c
@@ -835,7 +835,7 @@ retry:
         }
 
         if (!found) {
-            virDomainEventPtr event;
+            virObjectEventPtr event;
             char *name;
             unsigned char uuid[VIR_UUID_BUFLEN];
 
@@ -918,7 +918,7 @@ retry:
         }
 
         if (!found) {
-            virDomainEventPtr event =
+            virObjectEventPtr event =
                 virDomainEventNew(-1,
                                   priv->activeDomainList->doms[j]->name,
                                   priv->activeDomainList->doms[j]->uuid,
diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c
index 961dfc6..8036adc 100644
--- a/tests/qemuhotplugtest.c
+++ b/tests/qemuhotplugtest.c
@@ -344,7 +344,7 @@ mymain(void)
     if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0)
         return EXIT_FAILURE;
 
-    if (!(driver.domainEventState = virDomainEventStateNew()))
+    if (!(driver.domainEventState = virObjectEventStateNew()))
         return EXIT_FAILURE;
 
     driver.lockManager = virLockManagerPluginNew("nop", "qemu",
-- 
1.8.4.2




More information about the libvir-list mailing list