Return count of callbacks when registering callbacks

When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID

* src/conf/domain_event.c, src/conf/domain_event.h,
  src/libvirt_private.syms: Return count of callbacks when
  registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
  src/qemu/qemu_driver.c, src/remote/remote_driver.c,
  src/remote/remote_driver.c, src/uml/uml_driver.c,
  src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
  for change in APIs
This commit is contained in:
Daniel P. Berrange 2011-12-13 23:38:54 +00:00
parent a86bbc6003
commit d09f6ba5fe
11 changed files with 100 additions and 80 deletions

View File

@ -357,7 +357,7 @@ virDomainEventCallbackListAdd(virConnectPtr conn,
return virDomainEventCallbackListAddID(conn, cbList, NULL, return virDomainEventCallbackListAddID(conn, cbList, NULL,
VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(callback), VIR_DOMAIN_EVENT_CALLBACK(callback),
opaque, freecb); opaque, freecb, NULL);
} }
@ -368,6 +368,7 @@ virDomainEventCallbackListAdd(virConnectPtr conn,
* @eventID: the event ID * @eventID: the event ID
* @callback: the callback to add * @callback: the callback to add
* @opaque: opaque data tio pass to callback * @opaque: opaque data tio pass to callback
* @callbackID: filled with callback ID
* *
* Internal function to add a callback from a virDomainEventCallbackListPtr * Internal function to add a callback from a virDomainEventCallbackListPtr
*/ */
@ -378,10 +379,12 @@ virDomainEventCallbackListAddID(virConnectPtr conn,
int eventID, int eventID,
virConnectDomainEventGenericCallback callback, virConnectDomainEventGenericCallback callback,
void *opaque, void *opaque,
virFreeCallback freecb) virFreeCallback freecb,
int *callbackID)
{ {
virDomainEventCallbackPtr event; virDomainEventCallbackPtr event;
int i; int i;
int ret = 0;
/* Check incoming */ /* Check incoming */
if ( !cbList ) { if ( !cbList ) {
@ -427,7 +430,17 @@ virDomainEventCallbackListAddID(virConnectPtr conn,
event->callbackID = cbList->nextID++; event->callbackID = cbList->nextID++;
return event->callbackID; for (i = 0 ; i < cbList->count ; i++) {
if (cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE &&
cbList->callbacks[i]->conn == conn &&
!cbList->callbacks[i]->deleted)
ret++;
}
if (callbackID)
*callbackID = event->callbackID;
return ret;
no_memory: no_memory:
virReportOOMError(); virReportOOMError();
@ -1358,20 +1371,20 @@ virDomainEventStateDeregister(virConnectPtr conn,
/** /**
* virDomainEventStateDeregisterAny: * virDomainEventStateDeregisterID:
* @state: domain event state * @state: domain event state
* @conn: connection to associate with callback * @conn: connection to associate with callback
* @callbackID: ID of the function to remove from event * @callbackID: ID of the function to remove from event
* *
* Unregister the function @callbackID with connection @conn, * Unregister the function @callbackID with connection @conn,
* from @state, for lifecycle events. * from @state, for events.
* *
* Returns: the number of lifecycle callbacks still registered, or -1 on error * Returns: the number of callbacks still registered, or -1 on error
*/ */
int int
virDomainEventStateDeregisterAny(virConnectPtr conn, virDomainEventStateDeregisterID(virConnectPtr conn,
virDomainEventStatePtr state, virDomainEventStatePtr state,
int callbackID) int callbackID)
{ {
int ret; int ret;

View File

@ -80,7 +80,8 @@ int virDomainEventCallbackListAddID(virConnectPtr conn,
int eventID, int eventID,
virConnectDomainEventGenericCallback cb, virConnectDomainEventGenericCallback cb,
void *opaque, void *opaque,
virFreeCallback freecb) virFreeCallback freecb,
int *callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(5); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(5);
@ -242,9 +243,9 @@ virDomainEventStateDeregister(virConnectPtr conn,
virConnectDomainEventCallback callback) virConnectDomainEventCallback callback)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
int int
virDomainEventStateDeregisterAny(virConnectPtr conn, virDomainEventStateDeregisterID(virConnectPtr conn,
virDomainEventStatePtr state, virDomainEventStatePtr state,
int callbackID) int callbackID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
#endif #endif

View File

@ -511,7 +511,7 @@ virDomainEventRebootNew;
virDomainEventRebootNewFromDom; virDomainEventRebootNewFromDom;
virDomainEventRebootNewFromObj; virDomainEventRebootNewFromObj;
virDomainEventStateDeregister; virDomainEventStateDeregister;
virDomainEventStateDeregisterAny; virDomainEventStateDeregisterID;
virDomainEventStateFlush; virDomainEventStateFlush;
virDomainEventStateFree; virDomainEventStateFree;
virDomainEventStateNew; virDomainEventStateNew;

View File

@ -3851,10 +3851,11 @@ libxlDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, int eventID,
int ret; int ret;
libxlDriverLock(driver); libxlDriverLock(driver);
ret = virDomainEventCallbackListAddID(conn, if (virDomainEventCallbackListAddID(conn,
driver->domainEventState->callbacks, driver->domainEventState->callbacks,
dom, eventID, callback, opaque, dom, eventID, callback, opaque,
freecb); freecb, &ret) < 0)
ret = -1;
libxlDriverUnlock(driver); libxlDriverUnlock(driver);
return ret; return ret;
@ -3868,9 +3869,9 @@ libxlDomainEventDeregisterAny(virConnectPtr conn, int callbackID)
int ret; int ret;
libxlDriverLock(driver); libxlDriverLock(driver);
ret = virDomainEventStateDeregisterAny(conn, ret = virDomainEventStateDeregisterID(conn,
driver->domainEventState, driver->domainEventState,
callbackID); callbackID);
libxlDriverUnlock(driver); libxlDriverUnlock(driver);
return ret; return ret;

View File

@ -2164,10 +2164,11 @@ lxcDomainEventRegisterAny(virConnectPtr conn,
int ret; int ret;
lxcDriverLock(driver); lxcDriverLock(driver);
ret = virDomainEventCallbackListAddID(conn, if (virDomainEventCallbackListAddID(conn,
driver->domainEventState->callbacks, driver->domainEventState->callbacks,
dom, eventID, dom, eventID,
callback, opaque, freecb); callback, opaque, freecb, &ret) < 0)
ret = -1;
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return ret; return ret;
@ -2182,9 +2183,9 @@ lxcDomainEventDeregisterAny(virConnectPtr conn,
int ret; int ret;
lxcDriverLock(driver); lxcDriverLock(driver);
ret = virDomainEventStateDeregisterAny(conn, ret = virDomainEventStateDeregisterID(conn,
driver->domainEventState, driver->domainEventState,
callbackID); callbackID);
lxcDriverUnlock(driver); lxcDriverUnlock(driver);
return ret; return ret;

View File

@ -7997,10 +7997,11 @@ qemuDomainEventRegisterAny(virConnectPtr conn,
int ret; int ret;
qemuDriverLock(driver); qemuDriverLock(driver);
ret = virDomainEventCallbackListAddID(conn, if (virDomainEventCallbackListAddID(conn,
driver->domainEventState->callbacks, driver->domainEventState->callbacks,
dom, eventID, dom, eventID,
callback, opaque, freecb); callback, opaque, freecb, &ret) < 0)
ret = -1;
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
return ret; return ret;
@ -8015,9 +8016,9 @@ qemuDomainEventDeregisterAny(virConnectPtr conn,
int ret; int ret;
qemuDriverLock(driver); qemuDriverLock(driver);
ret = virDomainEventStateDeregisterAny(conn, ret = virDomainEventStateDeregisterID(conn,
driver->domainEventState, driver->domainEventState,
callbackID); callbackID);
qemuDriverUnlock(driver); qemuDriverUnlock(driver);
return ret; return ret;

View File

@ -3120,6 +3120,7 @@ static int remoteDomainEventRegister(virConnectPtr conn,
{ {
int rv = -1; int rv = -1;
struct private_data *priv = conn->privateData; struct private_data *priv = conn->privateData;
int count;
remoteDriverLock(priv); remoteDriverLock(priv);
@ -3128,15 +3129,13 @@ static int remoteDomainEventRegister(virConnectPtr conn,
goto done; goto done;
} }
if (virDomainEventCallbackListAdd(conn, priv->domainEventState->callbacks, if ((count = virDomainEventCallbackListAdd(conn, priv->domainEventState->callbacks,
callback, opaque, freecb) < 0) { callback, opaque, freecb)) < 0) {
remoteError(VIR_ERR_RPC, "%s", _("adding cb to list")); remoteError(VIR_ERR_RPC, "%s", _("adding cb to list"));
goto done; goto done;
} }
if (virDomainEventCallbackListCountID(conn, if (count == 1) {
priv->domainEventState->callbacks,
VIR_DOMAIN_EVENT_ID_LIFECYCLE) == 1) {
/* Tell the server when we are the first callback deregistering */ /* Tell the server when we are the first callback deregistering */
if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_REGISTER, if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_REGISTER,
(xdrproc_t) xdr_void, (char *) NULL, (xdrproc_t) xdr_void, (char *) NULL,
@ -3760,6 +3759,7 @@ static int remoteDomainEventRegisterAny(virConnectPtr conn,
struct private_data *priv = conn->privateData; struct private_data *priv = conn->privateData;
remote_domain_events_register_any_args args; remote_domain_events_register_any_args args;
int callbackID; int callbackID;
int count;
remoteDriverLock(priv); remoteDriverLock(priv);
@ -3768,19 +3768,18 @@ static int remoteDomainEventRegisterAny(virConnectPtr conn,
goto done; goto done;
} }
if ((callbackID = virDomainEventCallbackListAddID(conn, if ((count = virDomainEventCallbackListAddID(conn,
priv->domainEventState->callbacks, priv->domainEventState->callbacks,
dom, eventID, dom, eventID,
callback, opaque, freecb)) < 0) { callback, opaque, freecb,
remoteError(VIR_ERR_RPC, "%s", _("adding cb to list")); &callbackID)) < 0) {
goto done; remoteError(VIR_ERR_RPC, "%s", _("adding cb to list"));
goto done;
} }
/* If this is the first callback for this eventID, we need to enable /* If this is the first callback for this eventID, we need to enable
* events on the server */ * events on the server */
if (virDomainEventCallbackListCountID(conn, if (count == 1) {
priv->domainEventState->callbacks,
eventID) == 1) {
args.eventID = eventID; args.eventID = eventID;
if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_REGISTER_ANY, if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_REGISTER_ANY,
@ -3818,9 +3817,9 @@ static int remoteDomainEventDeregisterAny(virConnectPtr conn,
goto done; goto done;
} }
if (virDomainEventStateDeregisterAny(conn, if (virDomainEventStateDeregisterID(conn,
priv->domainEventState, priv->domainEventState,
callbackID) < 0) callbackID) < 0)
goto done; goto done;
/* If that was the last callback for this eventID, we need to disable /* If that was the last callback for this eventID, we need to disable

View File

@ -5442,10 +5442,11 @@ testDomainEventRegisterAny(virConnectPtr conn,
int ret; int ret;
testDriverLock(driver); testDriverLock(driver);
ret = virDomainEventCallbackListAddID(conn, if (virDomainEventCallbackListAddID(conn,
driver->domainEventState->callbacks, driver->domainEventState->callbacks,
dom, eventID, dom, eventID,
callback, opaque, freecb); callback, opaque, freecb, &ret) < 0)
ret = -1;
testDriverUnlock(driver); testDriverUnlock(driver);
return ret; return ret;
@ -5459,9 +5460,9 @@ testDomainEventDeregisterAny(virConnectPtr conn,
int ret; int ret;
testDriverLock(driver); testDriverLock(driver);
ret = virDomainEventStateDeregisterAny(conn, ret = virDomainEventStateDeregisterID(conn,
driver->domainEventState, driver->domainEventState,
callbackID); callbackID);
testDriverUnlock(driver); testDriverUnlock(driver);
return ret; return ret;

View File

@ -2483,10 +2483,11 @@ umlDomainEventRegisterAny(virConnectPtr conn,
int ret; int ret;
umlDriverLock(driver); umlDriverLock(driver);
ret = virDomainEventCallbackListAddID(conn, if (virDomainEventCallbackListAddID(conn,
driver->domainEventState->callbacks, driver->domainEventState->callbacks,
dom, eventID, dom, eventID,
callback, opaque, freecb); callback, opaque, freecb, &ret) < 0)
ret = -1;
umlDriverUnlock(driver); umlDriverUnlock(driver);
return ret; return ret;
@ -2501,9 +2502,9 @@ umlDomainEventDeregisterAny(virConnectPtr conn,
int ret; int ret;
umlDriverLock(driver); umlDriverLock(driver);
ret = virDomainEventStateDeregisterAny(conn, ret = virDomainEventStateDeregisterID(conn,
driver->domainEventState, driver->domainEventState,
callbackID); callbackID);
umlDriverUnlock(driver); umlDriverUnlock(driver);
return ret; return ret;

View File

@ -7280,13 +7280,14 @@ static int vboxDomainEventRegisterAny(virConnectPtr conn,
* later you can iterate over them * later you can iterate over them
*/ */
ret = virDomainEventCallbackListAddID(conn, data->domainEvents->callbacks, if (virDomainEventCallbackListAddID(conn, data->domainEvents->callbacks,
dom, eventID, dom, eventID,
callback, opaque, freecb); callback, opaque, freecb, &ret) < 0)
ret = -1;
VIR_DEBUG("virDomainEventCallbackListAddID (ret = %d) ( conn: %p, " VIR_DEBUG("virDomainEventCallbackListAddID (ret = %d) ( conn: %p, "
"data->domainEvents->callbacks: %p, callback: %p, opaque: %p, " "data->domainEvents->callbacks: %p, callback: %p, opaque: %p, "
"freecb: %p )", ret, conn, data->domainEvents->callbacks, callback, "freecb: %p )", ret, conn, data->domainEvents->callbacks, callback,
opaque, freecb); opaque, freecb);
} }
} }
@ -7312,8 +7313,8 @@ static int vboxDomainEventDeregisterAny(virConnectPtr conn,
*/ */
vboxDriverLock(data); vboxDriverLock(data);
cnt = virDomainEventStateDeregisterAny(conn, data->domainEvents, cnt = virDomainEventStateDeregisterID(conn, data->domainEvents,
callbackID); callbackID);
if (data->vboxCallback && cnt == 0) { if (data->vboxCallback && cnt == 0) {
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback); data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);

View File

@ -1897,9 +1897,10 @@ xenUnifiedDomainEventRegisterAny(virConnectPtr conn,
return -1; return -1;
} }
ret = virDomainEventCallbackListAddID(conn, priv->domainEvents->callbacks, if (virDomainEventCallbackListAddID(conn, priv->domainEvents->callbacks,
dom, eventID, dom, eventID,
callback, opaque, freefunc); callback, opaque, freefunc, &ret) < 0)
ret = -1;
xenUnifiedUnlock(priv); xenUnifiedUnlock(priv);
return (ret); return (ret);
@ -1919,9 +1920,9 @@ xenUnifiedDomainEventDeregisterAny(virConnectPtr conn,
return -1; return -1;
} }
ret = virDomainEventStateDeregisterAny(conn, ret = virDomainEventStateDeregisterID(conn,
priv->domainEvents, priv->domainEvents,
callbackID); callbackID);
xenUnifiedUnlock(priv); xenUnifiedUnlock(priv);
return ret; return ret;