summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2011-04-18 16:56:08 +0100
committerRichard W.M. Jones <rjones@redhat.com>2011-04-18 22:23:33 +0100
commit76435db1adc4023a76d79c25d47a761f6ea47474 (patch)
treed9f98836b0570b8bc07c456b8b310663892d2f1f
parent5a9d47dae14866c4c052d29a5c0aa676f0c1ed94 (diff)
downloadlibguestfs-76435db1adc4023a76d79c25d47a761f6ea47474.tar.gz
libguestfs-76435db1adc4023a76d79c25d47a761f6ea47474.tar.xz
libguestfs-76435db1adc4023a76d79c25d47a761f6ea47474.zip
python: Release Python GIL while running libguestfs calls.
Release the Python global interpreter lock while running libguestfs calls. We don't release it around guestfs_create() because that is a short call that just allocates memory. We do release it around guestfs_close() since that is a potentially long-running (it can call wait(2) amongst other things). We also release it around all the other generated Python calls. We don't yet support callbacks into Python code (ie. the new event API). But when we do in future, we will need to also handle the GIL around those callbacks. This code is adapted from libvirt's python/typewrappers.h. Thanks to Dan Berrange for showing us how to do this properly. (cherry picked from commit 08dc4a87b92435678780e9c49fe3bc1e7465d99f)
-rw-r--r--generator/generator_python.ml19
1 files changed, 19 insertions, 0 deletions
diff --git a/generator/generator_python.ml b/generator/generator_python.ml
index 9514e4ad..8606db59 100644
--- a/generator/generator_python.ml
+++ b/generator/generator_python.ml
@@ -180,6 +180,7 @@ py_guestfs_create (PyObject *self, PyObject *args)
static PyObject *
py_guestfs_close (PyObject *self, PyObject *args)
{
+ PyThreadState *py_save = NULL;
PyObject *py_g;
guestfs_h *g;
@@ -187,7 +188,11 @@ py_guestfs_close (PyObject *self, PyObject *args)
return NULL;
g = get_handle (py_g);
+ if (PyEval_ThreadsInitialized ())
+ py_save = PyEval_SaveThread ();
guestfs_close (g);
+ if (PyEval_ThreadsInitialized ())
+ PyEval_RestoreThread (py_save);
Py_INCREF (Py_None);
return Py_None;
@@ -284,6 +289,7 @@ py_guestfs_close (PyObject *self, PyObject *args)
pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
pr "{\n";
+ pr " PyThreadState *py_save = NULL;\n";
pr " PyObject *py_g;\n";
pr " guestfs_h *g;\n";
pr " PyObject *py_r;\n";
@@ -440,6 +446,14 @@ py_guestfs_close (PyObject *self, PyObject *args)
pr "\n"
);
+ (* Release Python GIL while running. This code is from
+ * libvirt/python/typewrappers.h. Thanks to Dan Berrange for
+ * showing us how to do this properly.
+ *)
+ pr " if (PyEval_ThreadsInitialized ())\n";
+ pr " py_save = PyEval_SaveThread ();\n";
+ pr "\n";
+
if optargs = [] then
pr " r = guestfs_%s " name
else
@@ -447,6 +461,11 @@ py_guestfs_close (PyObject *self, PyObject *args)
generate_c_call_args ~handle:"g" style;
pr ";\n";
+ pr "\n";
+ pr " if (PyEval_ThreadsInitialized ())\n";
+ pr " PyEval_RestoreThread (py_save);\n";
+ pr "\n";
+
List.iter (
function
| Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _