mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 21:34:54 +03:00
datatypes: Introduce some admin-related close callback handling helpers
Well, there were three different spots where closeCallback->freeCallback was
called, not looking the same --> potential for bugs - and there indeed is a bug
with refcounting of the @conn object. So this patch partially follows the path
set by commit 24dbb69f
by introducing some close callback helpers both to
replace all the spots where we call clean the close callback data with a
dedicated function and to be able to fix the refcounting bug causing a memleak.
Signed-off-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
d46a1e5d45
commit
7cea74a3b2
@ -47,6 +47,7 @@ src/cpu/cpu_arm.c
|
||||
src/cpu/cpu_map.c
|
||||
src/cpu/cpu_ppc64.c
|
||||
src/cpu/cpu_x86.c
|
||||
src/datatypes.c
|
||||
src/driver.c
|
||||
src/esx/esx_driver.c
|
||||
src/esx/esx_network_driver.c
|
||||
|
@ -935,6 +935,68 @@ virAdmConnectCloseCallbackDataDispose(void *obj)
|
||||
virObjectUnlock(cb_data);
|
||||
}
|
||||
|
||||
void
|
||||
virAdmConnectCloseCallbackDataReset(virAdmConnectCloseCallbackDataPtr cbdata)
|
||||
{
|
||||
if (cbdata->freeCallback)
|
||||
cbdata->freeCallback(cbdata->opaque);
|
||||
|
||||
virObjectUnref(cbdata->conn);
|
||||
cbdata->conn = NULL;
|
||||
cbdata->freeCallback = NULL;
|
||||
cbdata->callback = NULL;
|
||||
cbdata->opaque = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
virAdmConnectCloseCallbackDataUnregister(virAdmConnectCloseCallbackDataPtr cbdata,
|
||||
virAdmConnectCloseFunc cb)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
virObjectLock(cbdata);
|
||||
if (cbdata->callback != cb) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("A different callback was requested"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
virAdmConnectCloseCallbackDataReset(cbdata);
|
||||
ret = 0;
|
||||
cleanup:
|
||||
virObjectUnlock(cbdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
virAdmConnectCloseCallbackDataRegister(virAdmConnectCloseCallbackDataPtr cbdata,
|
||||
virAdmConnectPtr conn,
|
||||
virAdmConnectCloseFunc cb,
|
||||
void *opaque,
|
||||
virFreeCallback freecb)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
virObjectLock(cbdata);
|
||||
|
||||
if (cbdata->callback) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("A close callback is already registered"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
virObjectRef(conn);
|
||||
cbdata->conn = conn;
|
||||
cbdata->callback = cb;
|
||||
cbdata->opaque = opaque;
|
||||
cbdata->freeCallback = freecb;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
virObjectUnlock(conn->closeCallback);
|
||||
return ret;
|
||||
}
|
||||
|
||||
virAdmServerPtr
|
||||
virAdmGetServer(virAdmConnectPtr conn, const char *name)
|
||||
{
|
||||
|
@ -722,5 +722,13 @@ void virConnectCloseCallbackDataCall(virConnectCloseCallbackDataPtr close,
|
||||
int reason);
|
||||
virConnectCloseFunc
|
||||
virConnectCloseCallbackDataGetCallback(virConnectCloseCallbackDataPtr close);
|
||||
void virAdmConnectCloseCallbackDataReset(virAdmConnectCloseCallbackDataPtr cbdata);
|
||||
int virAdmConnectCloseCallbackDataRegister(virAdmConnectCloseCallbackDataPtr cbdata,
|
||||
virAdmConnectPtr conn,
|
||||
virAdmConnectCloseFunc cb,
|
||||
void *opaque,
|
||||
virFreeCallback freecb);
|
||||
int virAdmConnectCloseCallbackDataUnregister(virAdmConnectCloseCallbackDataPtr cbdata,
|
||||
virAdmConnectCloseFunc cb);
|
||||
|
||||
#endif /* __VIR_DATATYPES_H__ */
|
||||
|
@ -29,6 +29,9 @@ xdr_admin_server_set_threadpool_parameters_args;
|
||||
# datatypes.h
|
||||
virAdmClientClass;
|
||||
virAdmConnectClass;
|
||||
virAdmConnectCloseCallbackDataRegister;
|
||||
virAdmConnectCloseCallbackDataReset;
|
||||
virAdmConnectCloseCallbackDataUnregister;
|
||||
virAdmGetServer;
|
||||
virAdmServerClass;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user