On Wed, Nov 25, 2009 at 12:06:03PM +0000, Daniel P. Berrange wrote: > * libvirt-override.c: Add many missing calls to allow threading > when entering C code, otherwise python blocks & then deadlocks > when we have an async event to dispatch back into python code > --- > python/libvirt-override.c | 106 ++++++++++++++++++++++++++++++++++++++++---- > 1 files changed, 96 insertions(+), 10 deletions(-) > > diff --git a/python/libvirt-override.c b/python/libvirt-override.c > index b885190..0f7db9c 100644 > --- a/python/libvirt-override.c > +++ b/python/libvirt-override.c > @@ -67,7 +67,10 @@ libvirt_virDomainBlockStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { > return(NULL); > domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virDomainBlockStats(domain, path, &stats, sizeof(stats)); > + LIBVIRT_END_ALLOW_THREADS; > + > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -96,7 +99,10 @@ libvirt_virDomainInterfaceStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) > return(NULL); > domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virDomainInterfaceStats(domain, path, &stats, sizeof(stats)); > + LIBVIRT_END_ALLOW_THREADS; > + > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -128,7 +134,9 @@ libvirt_virDomainGetSchedulerType(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virDomainGetSchedulerType(domain, &nparams); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval == NULL) > return VIR_PY_NONE; > > @@ -150,6 +158,7 @@ libvirt_virDomainGetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, > virDomainPtr domain; > PyObject *pyobj_domain, *info; > char *c_retval; > + int i_retval; > int nparams, i; > virSchedParameterPtr params; > > @@ -158,7 +167,10 @@ libvirt_virDomainGetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virDomainGetSchedulerType(domain, &nparams); > + LIBVIRT_END_ALLOW_THREADS; > + > if (c_retval == NULL) > return VIR_PY_NONE; > free(c_retval); > @@ -166,7 +178,11 @@ libvirt_virDomainGetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, > if ((params = malloc(sizeof(*params)*nparams)) == NULL) > return VIR_PY_NONE; > > - if (virDomainGetSchedulerParameters(domain, params, &nparams) < 0) { > + LIBVIRT_BEGIN_ALLOW_THREADS; > + i_retval = virDomainGetSchedulerParameters(domain, params, &nparams); > + LIBVIRT_END_ALLOW_THREADS; > + > + if (i_retval < 0) { > free(params); > return VIR_PY_NONE; > } > @@ -223,6 +239,7 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, > virDomainPtr domain; > PyObject *pyobj_domain, *info; > char *c_retval; > + int i_retval; > int nparams, i; > virSchedParameterPtr params; > > @@ -231,7 +248,10 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virDomainGetSchedulerType(domain, &nparams); > + LIBVIRT_END_ALLOW_THREADS; > + > if (c_retval == NULL) > return VIR_PY_INT_FAIL; > free(c_retval); > @@ -239,7 +259,11 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, > if ((params = malloc(sizeof(*params)*nparams)) == NULL) > return VIR_PY_INT_FAIL; > > - if (virDomainGetSchedulerParameters(domain, params, &nparams) < 0) { > + LIBVIRT_BEGIN_ALLOW_THREADS; > + i_retval = virDomainGetSchedulerParameters(domain, params, &nparams); > + LIBVIRT_END_ALLOW_THREADS; > + > + if (i_retval < 0) { > free(params); > return VIR_PY_INT_FAIL; > } > @@ -292,7 +316,10 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, > } > } > > - if (virDomainSetSchedulerParameters(domain, params, nparams) < 0) { > + LIBVIRT_BEGIN_ALLOW_THREADS; > + i_retval = virDomainSetSchedulerParameters(domain, params, nparams); > + LIBVIRT_END_ALLOW_THREADS; > + if (i_retval < 0) { > free(params); > return VIR_PY_INT_FAIL; > } > @@ -311,13 +338,17 @@ libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED, > virVcpuInfoPtr cpuinfo = NULL; > unsigned char *cpumap = NULL; > int cpumaplen, i; > + int i_retval; > > if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetVcpus", > &pyobj_domain)) > return(NULL); > domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); > > - if (virNodeGetInfo(virDomainGetConnect(domain), &nodeinfo) != 0) > + LIBVIRT_BEGIN_ALLOW_THREADS; > + i_retval = virNodeGetInfo(virDomainGetConnect(domain), &nodeinfo); > + LIBVIRT_END_ALLOW_THREADS; > + if (i_retval < 0) > return VIR_PY_NONE; > > if (virDomainGetInfo(domain, &dominfo) != 0) > @@ -330,9 +361,12 @@ libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED, > if ((cpumap = malloc(dominfo.nrVirtCpu * cpumaplen)) == NULL) > goto cleanup; > > - if (virDomainGetVcpus(domain, > - cpuinfo, dominfo.nrVirtCpu, > - cpumap, cpumaplen) < 0) > + LIBVIRT_BEGIN_ALLOW_THREADS; > + i_retval = virDomainGetVcpus(domain, > + cpuinfo, dominfo.nrVirtCpu, > + cpumap, cpumaplen); > + LIBVIRT_END_ALLOW_THREADS; > + if (i_retval < 0) > goto cleanup; > > /* convert to a Python tuple of long objects */ > @@ -395,13 +429,17 @@ libvirt_virDomainPinVcpu(PyObject *self ATTRIBUTE_UNUSED, > virNodeInfo nodeinfo; > unsigned char *cpumap; > int cpumaplen, i, vcpu; > + int i_retval; > > if (!PyArg_ParseTuple(args, (char *)"OiO:virDomainPinVcpu", > &pyobj_domain, &vcpu, &pycpumap)) > return(NULL); > domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); > > - if (virNodeGetInfo(virDomainGetConnect(domain), &nodeinfo) != 0) > + LIBVIRT_BEGIN_ALLOW_THREADS; > + i_retval = virNodeGetInfo(virDomainGetConnect(domain), &nodeinfo); > + LIBVIRT_END_ALLOW_THREADS; > + if (i_retval < 0) > return VIR_PY_INT_FAIL; > > cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo)); > @@ -418,10 +456,15 @@ libvirt_virDomainPinVcpu(PyObject *self ATTRIBUTE_UNUSED, > VIR_UNUSE_CPU(cpumap, i); > } > > - virDomainPinVcpu(domain, vcpu, cpumap, cpumaplen); > + LIBVIRT_BEGIN_ALLOW_THREADS; > + i_retval = virDomainPinVcpu(domain, vcpu, cpumap, cpumaplen); > + LIBVIRT_END_ALLOW_THREADS; > Py_DECREF(truth); > free(cpumap); > > + if (i_retval < 0) > + return VIR_PY_INT_FAIL; > + > return VIR_PY_INT_SUCCESS; > } > > @@ -471,7 +514,10 @@ libvirt_virConnGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > - if ((err = virConnGetLastError(conn)) == NULL) > + LIBVIRT_BEGIN_ALLOW_THREADS; > + err = virConnGetLastError(conn); > + LIBVIRT_END_ALLOW_THREADS; > + if (err == NULL) > return VIR_PY_NONE; > > if ((info = PyTuple_New(9)) == NULL) > @@ -793,7 +839,9 @@ libvirt_virConnectListDefinedDomains(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectNumOfDefinedDomains(conn); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -801,7 +849,9 @@ libvirt_virConnectListDefinedDomains(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectListDefinedDomains(conn, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -966,7 +1016,9 @@ libvirt_virConnectListNetworks(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectNumOfNetworks(conn); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -974,7 +1026,9 @@ libvirt_virConnectListNetworks(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectListNetworks(conn, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -1008,7 +1062,9 @@ libvirt_virConnectListDefinedNetworks(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectNumOfDefinedNetworks(conn); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -1016,7 +1072,9 @@ libvirt_virConnectListDefinedNetworks(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectListDefinedNetworks(conn, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -1211,7 +1269,9 @@ libvirt_virConnectListStoragePools(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectNumOfStoragePools(conn); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -1219,7 +1279,9 @@ libvirt_virConnectListStoragePools(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectListStoragePools(conn, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -1261,7 +1323,9 @@ libvirt_virConnectListDefinedStoragePools(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectNumOfDefinedStoragePools(conn); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -1269,7 +1333,9 @@ libvirt_virConnectListDefinedStoragePools(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectListDefinedStoragePools(conn, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -1311,7 +1377,9 @@ libvirt_virStoragePoolListVolumes(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > pool = (virStoragePoolPtr) PyvirStoragePool_Get(pyobj_pool); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virStoragePoolNumOfVolumes(pool); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -1319,7 +1387,9 @@ libvirt_virStoragePoolListVolumes(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virStoragePoolListVolumes(pool, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -1520,7 +1590,9 @@ libvirt_virNodeListDevices(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virNodeNumOfDevices(conn, cap, flags); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -1528,7 +1600,9 @@ libvirt_virNodeListDevices(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virNodeListDevices(conn, cap, names, c_retval, flags); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -1560,7 +1634,9 @@ libvirt_virNodeDeviceListCaps(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > dev = (virNodeDevicePtr) PyvirNodeDevice_Get(pyobj_dev); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virNodeDeviceNumOfCaps(dev); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -1568,7 +1644,9 @@ libvirt_virNodeDeviceListCaps(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virNodeDeviceListCaps(dev, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -1775,7 +1853,9 @@ libvirt_virConnectListInterfaces(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectNumOfInterfaces(conn); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -1783,7 +1863,9 @@ libvirt_virConnectListInterfaces(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectListInterfaces(conn, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; > @@ -1826,7 +1908,9 @@ libvirt_virConnectListDefinedInterfaces(PyObject *self ATTRIBUTE_UNUSED, > return(NULL); > conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); > > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectNumOfDefinedInterfaces(conn); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) > return VIR_PY_NONE; > > @@ -1834,7 +1918,9 @@ libvirt_virConnectListDefinedInterfaces(PyObject *self ATTRIBUTE_UNUSED, > names = malloc(sizeof(*names) * c_retval); > if (!names) > return VIR_PY_NONE; > + LIBVIRT_BEGIN_ALLOW_THREADS; > c_retval = virConnectListDefinedInterfaces(conn, names, c_retval); > + LIBVIRT_END_ALLOW_THREADS; > if (c_retval < 0) { > free(names); > return VIR_PY_NONE; Whoops ... that was a lot of them missing, ACK ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list