virConnectPtr
virGetConnect(void)
{
- virConnectPtr ret;
-
if (virDataTypesInitialize() < 0)
return NULL;
- if (!(ret = virObjectLockableNew(virConnectClass)))
- return NULL;
-
- if (!(ret->closeCallback = virObjectLockableNew(virConnectCloseCallbackDataClass)))
- goto error;
-
- return ret;
-
- error:
- virObjectUnref(ret);
- return NULL;
+ return virObjectLockableNew(virConnectClass);
}
/**
virResetError(&conn->err);
virURIFree(conn->uri);
-
- if (conn->closeCallback) {
- virObjectLock(conn->closeCallback);
- conn->closeCallback->callback = NULL;
- virObjectUnlock(conn->closeCallback);
-
- virObjectUnref(conn->closeCallback);
- }
}
virConnectCloseCallbackDataReset(obj);
}
+virConnectCloseCallbackDataPtr
+virNewConnectCloseCallbackData(void)
+{
+ if (virDataTypesInitialize() < 0)
+ return NULL;
+
+ return virObjectLockableNew(virConnectCloseCallbackDataClass);
+}
+
void virConnectCloseCallbackDataRegister(virConnectCloseCallbackDataPtr close,
virConnectPtr conn,
virConnectCloseFunc cb,
const char *password,
unsigned int flags);
+typedef int
+(*virDrvConnectRegisterCloseCallback)(virConnectPtr conn,
+ virConnectCloseFunc cb,
+ void *opaque,
+ virFreeCallback freecb);
+
+typedef int
+(*virDrvConnectUnregisterCloseCallback)(virConnectPtr conn,
+ virConnectCloseFunc cb);
+
typedef struct _virHypervisorDriver virHypervisorDriver;
typedef virHypervisorDriver *virHypervisorDriverPtr;
virDrvDomainGetFSInfo domainGetFSInfo;
virDrvDomainInterfaceAddresses domainInterfaceAddresses;
virDrvDomainSetUserPassword domainSetUserPassword;
+ virDrvConnectRegisterCloseCallback connectRegisterCloseCallback;
+ virDrvConnectUnregisterCloseCallback connectUnregisterCloseCallback;
};
virCheckConnectReturn(conn, -1);
virCheckNonNullArgGoto(cb, error);
- if (virConnectCloseCallbackDataGetCallback(conn->closeCallback) != NULL) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("A close callback is already registered"));
+ if (conn->driver->connectRegisterCloseCallback &&
+ conn->driver->connectRegisterCloseCallback(conn, cb, opaque, freecb) < 0)
goto error;
- }
-
- virConnectCloseCallbackDataRegister(conn->closeCallback, conn, cb,
- opaque, freecb);
return 0;
virCheckConnectReturn(conn, -1);
virCheckNonNullArgGoto(cb, error);
- if (virConnectCloseCallbackDataGetCallback(conn->closeCallback) != cb) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("A different callback was requested"));
+ if (conn->driver->connectUnregisterCloseCallback &&
+ conn->driver->connectUnregisterCloseCallback(conn, cb) < 0)
goto error;
- }
-
- virConnectCloseCallbackDataUnregister(conn->closeCallback, cb);
return 0;
bool serverEventFilter; /* Does server support modern event filtering */
virObjectEventStatePtr eventState;
+ virConnectCloseCallbackDataPtr closeCallback;
};
enum {
goto failed;
}
- virObjectRef(conn->closeCallback);
-
+ if (!(priv->closeCallback = virNewConnectCloseCallbackData()))
+ goto failed;
+ // ref on behalf of netclient
+ virObjectRef(priv->closeCallback);
virNetClientSetCloseCallback(priv->client,
remoteClientCloseFunc,
- conn->closeCallback, virObjectFreeCallback);
+ priv->closeCallback, virObjectFreeCallback);
if (!(priv->remoteProgram = virNetClientProgramNew(REMOTE_PROGRAM,
REMOTE_PROTOCOL_VERSION,
virNetClientClose(priv->client);
virObjectUnref(priv->client);
priv->client = NULL;
+ virObjectUnref(priv->closeCallback);
+ priv->closeCallback = NULL;
#ifdef WITH_GNUTLS
virObjectUnref(priv->tls);
priv->tls = NULL;
virNetClientSetCloseCallback(priv->client,
NULL,
- conn->closeCallback, virObjectFreeCallback);
+ priv->closeCallback, virObjectFreeCallback);
virNetClientClose(priv->client);
virObjectUnref(priv->client);
priv->client = NULL;
+ virObjectUnref(priv->closeCallback);
+ priv->closeCallback = NULL;
virObjectUnref(priv->remoteProgram);
virObjectUnref(priv->lxcProgram);
virObjectUnref(priv->qemuProgram);
return rv;
}
+static int
+remoteConnectRegisterCloseCallback(virConnectPtr conn,
+ virConnectCloseFunc cb,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ struct private_data *priv = conn->privateData;
+ int ret = -1;
+
+ remoteDriverLock(priv);
+
+ if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != NULL) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("A close callback is already registered"));
+ goto cleanup;
+ }
+
+ virConnectCloseCallbackDataRegister(priv->closeCallback, conn, cb,
+ opaque, freecb);
+ ret = 0;
+
+ cleanup:
+ remoteDriverUnlock(priv);
+
+ return ret;
+}
+
+static int
+remoteConnectUnregisterCloseCallback(virConnectPtr conn,
+ virConnectCloseFunc cb)
+{
+ struct private_data *priv = conn->privateData;
+ int ret = -1;
+
+ remoteDriverLock(priv);
+
+ if (virConnectCloseCallbackDataGetCallback(priv->closeCallback) != cb) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("A different callback was requested"));
+ goto cleanup;
+ }
+
+ virConnectCloseCallbackDataUnregister(priv->closeCallback, cb);
+ ret = 0;
+
+ cleanup:
+ remoteDriverUnlock(priv);
+
+ return ret;
+}
static int
remoteDomainRename(virDomainPtr dom, const char *new_name, unsigned int flags)
.domainInterfaceAddresses = remoteDomainInterfaceAddresses, /* 1.2.14 */
.domainSetUserPassword = remoteDomainSetUserPassword, /* 1.2.16 */
.domainRename = remoteDomainRename, /* 1.2.19 */
+ .connectRegisterCloseCallback = remoteConnectRegisterCloseCallback, /* 1.3.2 */
+ .connectUnregisterCloseCallback = remoteConnectUnregisterCloseCallback, /* 1.3.2 */
};
static virNetworkDriver network_driver = {