mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-04 07:53:50 +00:00
Make python bindings threaded, by dropping/acquiring Python GIL where needed
This commit is contained in:
parent
297a77f6da
commit
9e5645393e
@ -1,3 +1,12 @@
|
|||||||
|
Tue Oct 24 15:31:23 EDT 2006 Daniel P.Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* python/generator.py, python/libvir.c: Drop python interpreter
|
||||||
|
lock when calling into C functions, and re-grab when invoking
|
||||||
|
error callback.
|
||||||
|
* python/libvirt_wrap.h: Convenience macros for grabbing / dropping
|
||||||
|
the python interpreter lock in threaded environment.
|
||||||
|
|
||||||
|
|
||||||
Mon Oct 16 17:10:15 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
Mon Oct 16 17:10:15 CEST 2006 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* config.h.in configure.in libvirt.spec.in docs/libvir.html
|
* config.h.in configure.in libvirt.spec.in docs/libvir.html
|
||||||
|
@ -422,7 +422,9 @@ def print_function_wrapper(name, output, export, include):
|
|||||||
if c_convert != "":
|
if c_convert != "":
|
||||||
output.write(c_convert)
|
output.write(c_convert)
|
||||||
|
|
||||||
output.write(c_call)
|
output.write("LIBVIRT_BEGIN_ALLOW_THREADS;\n");
|
||||||
|
output.write(c_call);
|
||||||
|
output.write("LIBVIRT_END_ALLOW_THREADS;\n");
|
||||||
output.write(ret_convert)
|
output.write(ret_convert)
|
||||||
output.write("}\n\n")
|
output.write("}\n\n")
|
||||||
if cond != None and cond != "":
|
if cond != None and cond != "":
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
void initlibvirmod(void);
|
void initlibvirmod(void);
|
||||||
|
|
||||||
PyObject *libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args);
|
PyObject *libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args);
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* Global error handler at the Python level *
|
* Global error handler at the Python level *
|
||||||
@ -40,6 +42,8 @@ libvirt_virErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, virErrorPtr err)
|
|||||||
if ((err == NULL) || (err->code == VIR_ERR_OK))
|
if ((err == NULL) || (err->code == VIR_ERR_OK))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
LIBVIRT_ENSURE_THREAD_STATE;
|
||||||
|
|
||||||
if ((libvirt_virPythonErrorFuncHandler == NULL) ||
|
if ((libvirt_virPythonErrorFuncHandler == NULL) ||
|
||||||
(libvirt_virPythonErrorFuncHandler == Py_None)) {
|
(libvirt_virPythonErrorFuncHandler == Py_None)) {
|
||||||
virDefaultErrorFunc(err);
|
virDefaultErrorFunc(err);
|
||||||
@ -63,6 +67,8 @@ libvirt_virErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, virErrorPtr err)
|
|||||||
Py_XDECREF(list);
|
Py_XDECREF(list);
|
||||||
Py_XDECREF(result);
|
Py_XDECREF(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBVIRT_RELEASE_THREAD_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
@ -124,7 +130,9 @@ libvirt_virDomainFree(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
|
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
|
||||||
|
|
||||||
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
c_retval = virDomainFree(domain);
|
c_retval = virDomainFree(domain);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
py_retval = libvirt_intWrap((int) c_retval);
|
py_retval = libvirt_intWrap((int) c_retval);
|
||||||
return(py_retval);
|
return(py_retval);
|
||||||
}
|
}
|
||||||
@ -140,7 +148,9 @@ libvirt_virConnectClose(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
|
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
|
||||||
|
|
||||||
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
c_retval = virConnectClose(conn);
|
c_retval = virConnectClose(conn);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
py_retval = libvirt_intWrap((int) c_retval);
|
py_retval = libvirt_intWrap((int) c_retval);
|
||||||
return(py_retval);
|
return(py_retval);
|
||||||
}
|
}
|
||||||
@ -158,7 +168,9 @@ libvirt_virConnectListDomainsID(PyObject *self ATTRIBUTE_UNUSED,
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
|
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
|
||||||
|
|
||||||
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
c_retval = virConnectListDomains(conn, &ids[0], 500);
|
c_retval = virConnectListDomains(conn, &ids[0], 500);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
if (c_retval < 0) {
|
if (c_retval < 0) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return(Py_None);
|
return(Py_None);
|
||||||
@ -182,7 +194,9 @@ libvirt_virDomainGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
|
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
|
||||||
|
|
||||||
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
c_retval = virDomainGetInfo(domain, &info);
|
c_retval = virDomainGetInfo(domain, &info);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
if (c_retval < 0) {
|
if (c_retval < 0) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return(Py_None);
|
return(Py_None);
|
||||||
@ -209,7 +223,9 @@ libvirt_virNodeGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
|
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
|
||||||
|
|
||||||
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
c_retval = virNodeGetInfo(conn, &info);
|
c_retval = virNodeGetInfo(conn, &info);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
if (c_retval < 0) {
|
if (c_retval < 0) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return(Py_None);
|
return(Py_None);
|
||||||
@ -232,6 +248,7 @@ libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
|
|||||||
unsigned char uuid[16];
|
unsigned char uuid[16];
|
||||||
virDomainPtr domain;
|
virDomainPtr domain;
|
||||||
PyObject *pyobj_domain;
|
PyObject *pyobj_domain;
|
||||||
|
int c_retval;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetUUID", &pyobj_domain))
|
if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetUUID", &pyobj_domain))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -241,7 +258,11 @@ libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
|
|||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return(Py_None);
|
return(Py_None);
|
||||||
}
|
}
|
||||||
if (virDomainGetUUID(domain, &uuid[0]) < 0) {
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
|
c_retval = virDomainGetUUID(domain, &uuid[0]);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
|
|
||||||
|
if (c_retval < 0) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return(Py_None);
|
return(Py_None);
|
||||||
}
|
}
|
||||||
@ -268,7 +289,9 @@ libvirt_virDomainLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
|
|||||||
return(Py_None);
|
return(Py_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBVIRT_BEGIN_ALLOW_THREADS;
|
||||||
c_retval = virDomainLookupByUUID(conn, uuid);
|
c_retval = virDomainLookupByUUID(conn, uuid);
|
||||||
|
LIBVIRT_END_ALLOW_THREADS;
|
||||||
py_retval = libvirt_virDomainPtrWrap((virDomainPtr) c_retval);
|
py_retval = libvirt_virDomainPtrWrap((virDomainPtr) c_retval);
|
||||||
return(py_retval);
|
return(py_retval);
|
||||||
}
|
}
|
||||||
|
@ -48,3 +48,53 @@ PyObject * libvirt_charPtrConstWrap(const char *str);
|
|||||||
PyObject * libvirt_virConnectPtrWrap(virConnectPtr node);
|
PyObject * libvirt_virConnectPtrWrap(virConnectPtr node);
|
||||||
PyObject * libvirt_virDomainPtrWrap(virDomainPtr node);
|
PyObject * libvirt_virDomainPtrWrap(virDomainPtr node);
|
||||||
|
|
||||||
|
|
||||||
|
/* Provide simple macro statement wrappers (adapted from GLib, in turn from Perl):
|
||||||
|
* LIBVIRT_STMT_START { statements; } LIBVIRT_STMT_END;
|
||||||
|
* can be used as a single statement, as in
|
||||||
|
* if (x) LIBVIRT_STMT_START { ... } LIBVIRT_STMT_END; else ...
|
||||||
|
*
|
||||||
|
* When GCC is compiling C code in non-ANSI mode, it will use the
|
||||||
|
* compiler __extension__ to wrap the statements wihin `({' and '})' braces.
|
||||||
|
* When compiling on platforms where configure has defined
|
||||||
|
* HAVE_DOWHILE_MACROS, statements will be wrapped with `do' and `while (0)'.
|
||||||
|
* For any other platforms (SunOS4 is known to have this issue), wrap the
|
||||||
|
* statements with `if (1)' and `else (void) 0'.
|
||||||
|
*/
|
||||||
|
#if !(defined (LIBVIRT_STMT_START) && defined (LIBVIRT_STMT_END))
|
||||||
|
# if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
|
||||||
|
# define LIBVIRT_STMT_START (void) __extension__ (
|
||||||
|
# define LIBVIRT_STMT_END )
|
||||||
|
# else /* !(__GNUC__ && !__STRICT_ANSI__ && !__cplusplus) */
|
||||||
|
# if defined (HAVE_DOWHILE_MACROS)
|
||||||
|
# define LIBVIRT_STMT_START do
|
||||||
|
# define LIBVIRT_STMT_END while (0)
|
||||||
|
# else /* !HAVE_DOWHILE_MACROS */
|
||||||
|
# define LIBVIRT_STMT_START if (1)
|
||||||
|
# define LIBVIRT_STMT_END else (void) 0
|
||||||
|
# endif /* !HAVE_DOWHILE_MACROS */
|
||||||
|
# endif /* !(__GNUC__ && !__STRICT_ANSI__ && !__cplusplus) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIBVIRT_BEGIN_ALLOW_THREADS \
|
||||||
|
LIBVIRT_STMT_START { \
|
||||||
|
PyThreadState *_save = NULL; \
|
||||||
|
if (PyEval_ThreadsInitialized()) \
|
||||||
|
_save = PyEval_SaveThread();
|
||||||
|
|
||||||
|
#define LIBVIRT_END_ALLOW_THREADS \
|
||||||
|
if (PyEval_ThreadsInitialized()) \
|
||||||
|
PyEval_RestoreThread(_save); \
|
||||||
|
} LIBVIRT_STMT_END
|
||||||
|
|
||||||
|
#define LIBVIRT_ENSURE_THREAD_STATE \
|
||||||
|
LIBVIRT_STMT_START { \
|
||||||
|
PyGILState_STATE _save; \
|
||||||
|
if (PyEval_ThreadsInitialized()) \
|
||||||
|
_save = PyGILState_Ensure();
|
||||||
|
|
||||||
|
#define LIBVIRT_RELEASE_THREAD_STATE \
|
||||||
|
if (PyEval_ThreadsInitialized()) \
|
||||||
|
PyGILState_Release(_save); \
|
||||||
|
} LIBVIRT_STMT_END
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user