diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2011-12-13 10:39:17 +0000 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2011-12-19 11:08:09 +0000 |
commit | a86bbc6003201414e46b2146a32d1ba997149ef4 (patch) | |
tree | d568609e7c4af4b8c8b5b233cbade77f1637ad39 /src/vbox | |
parent | nwfilter: do not create ebtables chain unnecessarily (diff) | |
download | libvirt-a86bbc6003201414e46b2146a32d1ba997149ef4.tar.gz libvirt-a86bbc6003201414e46b2146a32d1ba997149ef4.tar.bz2 libvirt-a86bbc6003201414e46b2146a32d1ba997149ef4.zip |
Convert Xen & VBox drivers to use virDomainEventState
The Xen & VBox drivers deal with callbacks & dispatching of
events directly. All the other drivers use a timer to dispatch
events from a clean stack state, rather than deep inside the
drivers. Convert Xen & VBox over to virDomainEventState so
that they match behaviour of other drivers
* src/conf/domain_event.c: Return count of remaining
callbacks when unregistering event callback
* src/vbox/vbox_tmpl.c, src/xen/xen_driver.c,
src/xen/xen_driver.h: Convert to virDomainEventState
Diffstat (limited to 'src/vbox')
-rw-r--r-- | src/vbox/vbox_tmpl.c | 146 |
1 files changed, 77 insertions, 69 deletions
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 9b74a7ba0..7f13f903c 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -188,11 +188,9 @@ typedef struct { #else /* !(VBOX_API_VERSION == 2002) */ - /* An array of callbacks */ - virDomainEventCallbackListPtr domainEventCallbacks; - + /* Async event handling */ + virDomainEventStatePtr domainEvents; int fdWatch; - int domainEventDispatching; # if VBOX_API_VERSION <= 3002 /* IVirtualBoxCallback is used in VirtualBox 3.x only */ @@ -966,11 +964,52 @@ static void vboxUninitialize(vboxGlobalData *data) { #if VBOX_API_VERSION == 2002 /* No domainEventCallbacks in 2.2.* version */ #else /* !(VBOX_API_VERSION == 2002) */ - VIR_FREE(data->domainEventCallbacks); + virDomainEventStateFree(data->domainEvents); #endif /* !(VBOX_API_VERSION == 2002) */ VIR_FREE(data); } + +#if VBOX_API_VERSION == 2002 + /* No domainEventCallbacks in 2.2.* version */ +#else /* !(VBOX_API_VERSION == 2002) */ + +static void +vboxDomainEventDispatchFunc(virConnectPtr conn, + virDomainEventPtr event, + virConnectDomainEventGenericCallback cb, + void *cbopaque, + void *opaque) +{ + vboxGlobalData *data = opaque; + + /* + * Release the lock while the callback is running so that + * we're re-entrant safe for callback work - the callback + * may want to invoke other virt functions & we have already + * protected the one piece of state we have - the callback + * list + */ + vboxDriverUnlock(data); + virDomainEventDispatchDefaultFunc(conn, event, cb, cbopaque, NULL); + vboxDriverLock(data); +} + + +static void vboxDomainEventFlush(int timer ATTRIBUTE_UNUSED, void *opaque) +{ + virConnectPtr conn = opaque; + vboxGlobalData *data = conn->privateData; + + vboxDriverLock(data); + virDomainEventStateFlush(data->domainEvents, + vboxDomainEventDispatchFunc, + data); + vboxDriverUnlock(data); +} +#endif /* !(VBOX_API_VERSION == 2002) */ + + static virDrvOpenStatus vboxOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) @@ -1035,8 +1074,11 @@ static virDrvOpenStatus vboxOpen(virConnectPtr conn, #else /* !(VBOX_API_VERSION == 2002) */ - if (VIR_ALLOC(data->domainEventCallbacks) < 0) { - virReportOOMError(); + if (!(data->domainEvents = virDomainEventStateNew(vboxDomainEventFlush, + data, + NULL, + true))) { + vboxUninitialize(data); return VIR_DRV_OPEN_ERROR; } @@ -6770,7 +6812,6 @@ vboxCallbackOnMachineStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED, int event = 0; int detail = 0; - g_pVBoxGlobalData->domainEventDispatching = 1; vboxDriverLock(g_pVBoxGlobalData); VIR_DEBUG("IVirtualBoxCallback: %p, State: %d", pThis, state); @@ -6818,20 +6859,12 @@ vboxCallbackOnMachineStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED, ev = virDomainEventNewFromDom(dom, event, detail); - if (ev) { - virDomainEventDispatch(ev, - g_pVBoxGlobalData->domainEventCallbacks, - virDomainEventDispatchDefaultFunc, - NULL); - virDomainEventFree(ev); - } + if (ev) + virDomainEventStateQueue(g_pVBoxGlobalData->domainEvents, ev); } } - virDomainEventCallbackListPurgeMarked(g_pVBoxGlobalData->domainEventCallbacks); - vboxDriverUnlock(g_pVBoxGlobalData); - g_pVBoxGlobalData->domainEventDispatching = 0; return NS_OK; } @@ -6898,7 +6931,6 @@ vboxCallbackOnMachineRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED, int event = 0; int detail = 0; - g_pVBoxGlobalData->domainEventDispatching = 1; vboxDriverLock(g_pVBoxGlobalData); VIR_DEBUG("IVirtualBoxCallback: %p, registered: %s", pThis, registered ? "true" : "false"); @@ -6931,20 +6963,12 @@ vboxCallbackOnMachineRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED, ev = virDomainEventNewFromDom(dom, event, detail); - if (ev) { - virDomainEventDispatch(ev, - g_pVBoxGlobalData->domainEventCallbacks, - virDomainEventDispatchDefaultFunc, - NULL); - virDomainEventFree(ev); - } + if (ev) + virDomainEventStateQueue(g_pVBoxGlobalData->domainEvents, ev); } } - virDomainEventCallbackListPurgeMarked(g_pVBoxGlobalData->domainEventCallbacks); - vboxDriverUnlock(g_pVBoxGlobalData); - g_pVBoxGlobalData->domainEventDispatching = 0; return NS_OK; } @@ -7164,11 +7188,11 @@ static int vboxDomainEventRegister (virConnectPtr conn, * later you can iterate over them */ - ret = virDomainEventCallbackListAdd(conn, data->domainEventCallbacks, + ret = virDomainEventCallbackListAdd(conn, data->domainEvents->callbacks, callback, opaque, freecb); VIR_DEBUG("virDomainEventCallbackListAdd (ret = %d) ( conn: %p, " - "data->domainEventCallbacks: %p, callback: %p, opaque: %p, " - "freecb: %p )", ret, conn, data->domainEventCallbacks, callback, + "data->domainEvents->callbacks: %p, callback: %p, opaque: %p, " + "freecb: %p )", ret, conn, data->domainEvents->callbacks, callback, opaque, freecb); } } @@ -7188,31 +7212,23 @@ static int vboxDomainEventRegister (virConnectPtr conn, static int vboxDomainEventDeregister (virConnectPtr conn, virConnectDomainEventCallback callback) { VBOX_OBJECT_CHECK(conn, int, -1); + int cnt; /* Locking has to be there as callbacks are not * really fully thread safe */ vboxDriverLock(data); - if (data->domainEventDispatching) - ret = virDomainEventCallbackListMarkDelete(conn, data->domainEventCallbacks, - callback); - else - ret = virDomainEventCallbackListRemove(conn, data->domainEventCallbacks, - callback); + cnt = virDomainEventStateDeregister(conn, data->domainEvents, + callback); - if (data->vboxCallback) { - /* check count here of how many times register was called - * and only on the last de-register do the un-register call - */ - if (data->domainEventCallbacks && virDomainEventCallbackListCount(data->domainEventCallbacks) == 0) { - data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback); - VBOX_RELEASE(data->vboxCallback); + if (data->vboxCallback && cnt == 0) { + data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback); + VBOX_RELEASE(data->vboxCallback); - /* Remove the Event file handle on which we are listening as well */ - virEventRemoveHandle(data->fdWatch); - data->fdWatch = -1; - } + /* Remove the Event file handle on which we are listening as well */ + virEventRemoveHandle(data->fdWatch); + data->fdWatch = -1; } vboxDriverUnlock(data); @@ -7264,12 +7280,12 @@ static int vboxDomainEventRegisterAny(virConnectPtr conn, * later you can iterate over them */ - ret = virDomainEventCallbackListAddID(conn, data->domainEventCallbacks, + ret = virDomainEventCallbackListAddID(conn, data->domainEvents->callbacks, dom, eventID, callback, opaque, freecb); VIR_DEBUG("virDomainEventCallbackListAddID (ret = %d) ( conn: %p, " - "data->domainEventCallbacks: %p, callback: %p, opaque: %p, " - "freecb: %p )", ret, conn, data->domainEventCallbacks, callback, + "data->domainEvents->callbacks: %p, callback: %p, opaque: %p, " + "freecb: %p )", ret, conn, data->domainEvents->callbacks, callback, opaque, freecb); } } @@ -7289,31 +7305,23 @@ static int vboxDomainEventRegisterAny(virConnectPtr conn, static int vboxDomainEventDeregisterAny(virConnectPtr conn, int callbackID) { VBOX_OBJECT_CHECK(conn, int, -1); + int cnt; /* Locking has to be there as callbacks are not * really fully thread safe */ vboxDriverLock(data); - if (data->domainEventDispatching) - ret = virDomainEventCallbackListMarkDeleteID(conn, data->domainEventCallbacks, - callbackID); - else - ret = virDomainEventCallbackListRemoveID(conn, data->domainEventCallbacks, - callbackID); + cnt = virDomainEventStateDeregisterAny(conn, data->domainEvents, + callbackID); - if (data->vboxCallback) { - /* check count here of how many times register was called - * and only on the last de-register do the un-register call - */ - if (data->domainEventCallbacks && virDomainEventCallbackListCount(data->domainEventCallbacks) == 0) { - data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback); - VBOX_RELEASE(data->vboxCallback); + if (data->vboxCallback && cnt == 0) { + data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback); + VBOX_RELEASE(data->vboxCallback); - /* Remove the Event file handle on which we are listening as well */ - virEventRemoveHandle(data->fdWatch); - data->fdWatch = -1; - } + /* Remove the Event file handle on which we are listening as well */ + virEventRemoveHandle(data->fdWatch); + data->fdWatch = -1; } vboxDriverUnlock(data); |