[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libguestfs] [PATCH] python: Release Python GIL while running libguestfs calls.



-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines.  Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top
>From f189e41a951bb01216cec806d5afdca745529eaf Mon Sep 17 00:00:00 2001
From: Richard W.M. Jones <rjones redhat com>
Date: Mon, 18 Apr 2011 16:56:08 +0100
Subject: [PATCH] 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 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 if we do in future, we will need to also handle the GIL
around those callbacks.

This code is modified from libvirt/python/typewrappers.h.  Thanks to
Dan Berrange for showing us how to do this properly.
---
 generator/generator_python.ml |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/generator/generator_python.ml b/generator/generator_python.ml
index 9514e4a..8606db5 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 _
-- 
1.7.4.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]