From: Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
Reuse virConnectCloseCallback to implement connection close event functions.
This way we automatically meet multi-thread requirements on unregistering/notification.
---
src/vz/vz_driver.c | 26 ++++++++++++++++++++++++++
src/vz/vz_sdk.c | 29 +++++++++++++++++++++++++++++
src/vz/vz_utils.h | 3 +++
3 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index d9ddd4f..e3d0fdc 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -268,6 +268,9 @@ vzOpenDefault(virConnectPtr conn)
if (prlsdkSubscribeToPCSEvents(privconn))
goto error;
+ if (!(privconn->closeCallback = virGetConnectCloseCallback()))
+ goto error;
+
conn->privateData = privconn;
if (prlsdkLoadDomains(privconn))
@@ -276,6 +279,8 @@ vzOpenDefault(virConnectPtr conn)
return VIR_DRV_OPEN_SUCCESS;
error:
+ virObjectUnref(privconn->closeCallback);
+ privconn->closeCallback = NULL;
virObjectUnref(privconn->domains);
virObjectUnref(privconn->caps);
virStoragePoolObjListFree(&privconn->pools);
@@ -350,6 +355,8 @@ vzConnectClose(virConnectPtr conn)
virObjectUnref(privconn->caps);
virObjectUnref(privconn->xmlopt);
virObjectUnref(privconn->domains);
+ virObjectUnref(privconn->closeCallback);
+ privconn->closeCallback = NULL;
virObjectEventStateFree(privconn->domainEventState);
prlsdkDisconnect(privconn);
conn->privateData = NULL;
@@ -1337,6 +1344,23 @@ vzDomainBlockStatsFlags(virDomainPtr domain,
return ret;
}
+static int
+vzConnectRegisterCloseCallback(virConnectPtr conn,
+ virConnectCloseFunc cb,
+ void *opaque,
+ virFreeCallback freecb)
+{
+ vzConnPtr privconn = conn->privateData;
+ return virConnectCloseCallbackRegister(privconn->closeCallback, conn, cb, opaque,
freecb);
+}
+
+static int
+vzConnectUnregisterCloseCallback(virConnectPtr conn, virConnectCloseFunc cb
ATTRIBUTE_UNUSED)
+{
+ vzConnPtr privconn = conn->privateData;
+ virConnectCloseCallbackUnregister(privconn->closeCallback);
+ return 0;
+}
static virHypervisorDriver vzDriver = {
.name = "vz",
@@ -1389,6 +1413,8 @@ static virHypervisorDriver vzDriver = {
.domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
.domainBlockStats = vzDomainBlockStats, /* 1.3.0 */
.domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.3.0 */
+ .connectRegisterCloseCallback = vzConnectRegisterCloseCallback, /* 1.3.0 */
+ .connectUnregisterCloseCallback = vzConnectUnregisterCloseCallback, /* 1.3.0 */
};
static virConnectDriver vzConnectDriver = {
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index 388ea19..5f38709 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -1745,6 +1745,32 @@ prlsdkHandleVmEvent(vzConnPtr privconn, PRL_HANDLE prlEvent)
return;
}
+static
+void prlsdkHandleDispatcherConnectionClosed(vzConnPtr privconn)
+{
+ virConnectCloseCallbackCall(privconn->closeCallback,
VIR_CONNECT_CLOSE_REASON_EOF);
+}
+
+static void
+prlsdkHandleDispatcherEvent(vzConnPtr privconn, PRL_HANDLE prlEvent)
+{
+ PRL_RESULT pret = PRL_ERR_FAILURE;
+ PRL_EVENT_TYPE prlEventType;
+
+ pret = PrlEvent_GetType(prlEvent, &prlEventType);
+ prlsdkCheckRetGoto(pret, error);
+
+ switch (prlEventType) {
+ case PET_DSP_EVT_DISP_CONNECTION_CLOSED:
+ prlsdkHandleDispatcherConnectionClosed(privconn);
+ break;
+ default:
+ VIR_DEBUG("Skipping dispatcher event of type %d", prlEventType);
+ }
+ error:
+ return;
+}
+
static PRL_RESULT
prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
{
@@ -1772,6 +1798,9 @@ prlsdkEventsHandler(PRL_HANDLE prlEvent, PRL_VOID_PTR opaque)
// above function takes own of event
prlEvent = PRL_INVALID_HANDLE;
break;
+ case PIE_DISPATCHER:
+ prlsdkHandleDispatcherEvent(privconn, prlEvent);
+ break;
default:
VIR_DEBUG("Skipping event of issuer type %d", prlIssuerType);
}
diff --git a/src/vz/vz_utils.h b/src/vz/vz_utils.h
index 9b46bf9..b0dc3d8 100644
--- a/src/vz/vz_utils.h
+++ b/src/vz/vz_utils.h
@@ -32,6 +32,7 @@
# include "conf/network_conf.h"
# include "virthread.h"
# include "virjson.h"
+# include "datatypes.h"
# define vzParseError() \
virReportErrorHelper(VIR_FROM_TEST, VIR_ERR_OPERATION_FAILED, __FILE__, \
@@ -69,6 +70,8 @@ struct _vzConn {
virObjectEventStatePtr domainEventState;
virStorageDriverStatePtr storageState;
const char *drivername;
+ /* Immutable pointer, self-locking APIs */
+ virConnectCloseCallbackPtr closeCallback;
};
typedef struct _vzConn vzConn;
--
1.7.1