+Fri Nov 21 10:14:14 BST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+ Fix crash due to failure to unregister event callbacks on
+ connection close (David Lively)
+ * src/domain_event.c, src/domain_event.h: Helper for unregistering
+ all callbacks
+ * src/qemu_driver.c: Unregister all callbacks on connection close
+
Fri Nov 21 10:10:14 BST 2008 Daniel P. Berrange <berrange@redhat.com>
* src/Makefile.am: Include Xen compile flags for libvirt_driver.la
return -1;
}
+/**
+ * virDomainEventCallbackListRemoveConn:
+ * @conn: pointer to the connection
+ * @cbList: the list
+ *
+ * Internal function to remove all of a given connection's callback
+ * from a virDomainEventCallbackListPtr
+ */
+int
+virDomainEventCallbackListRemoveConn(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList)
+{
+ int old_count = cbList->count;
+ int i;
+ for (i = 0 ; i < cbList->count ; i++) {
+ if(cbList->callbacks[i]->conn == conn) {
+ virFreeCallback freecb = cbList->callbacks[i]->freecb;
+ if (freecb)
+ (*freecb)(cbList->callbacks[i]->opaque);
+ virUnrefConnect(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)));
+ cbList->count--;
+ i--;
+ }
+ }
+ if (cbList->count < old_count &&
+ VIR_REALLOC_N(cbList->callbacks, cbList->count) < 0) {
+ ; /* Failure to reduce memory allocation isn't fatal */
+ }
+ return 0;
+}
+
/**
* virDomainEventCallbackListAdd:
* @conn: pointer to the connection
virDomainEventCallbackListPtr cbList,
virConnectDomainEventCallback callback);
+int virDomainEventCallbackListRemoveConn(virConnectPtr conn,
+ virDomainEventCallbackListPtr cbList);
+
/**
* Dispatching domain events that come in while
* in a call / response rpc
}
static int qemudClose(virConnectPtr conn) {
- /*struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;*/
+ struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+
+ /* Get rid of callbacks registered for this conn */
+ virDomainEventCallbackListRemoveConn(conn, driver->domainEventCallbacks);
conn->privateData = NULL;