[PATCH] Python: Release GIL on blocking operations

Justin Mazzola Paluska jmp at MIT.EDU
Wed Aug 2 00:35:29 PDT 2006


Hi,

I noticed that the D-Bus Python bindings don't release the global
interpreter lock (GIL) when they block.  This causes all threads that
need the Python interpreter to block until the D-Bus call returns.
The attached patch releases/acquires the GIL around blocking D-Bus
operations.

I noticed this in another application I was writing, but have attached
minimal examples of why it's necessary.  Without the patch, the thread
printing *'s doesn't run; with the patch, the thread printing *'s runs
while the D-Bus thread is blocked.

Should I file a bug in the tracker with the patches?
	--Justin
-------------- next part --------------
diff --git a/dbus/dbus_bindings.pyx b/dbus/dbus_bindings.pyx
index c29dea2..bc0f78a 100644
--- a/dbus/dbus_bindings.pyx
+++ b/dbus/dbus_bindings.pyx
@@ -25,6 +25,9 @@ cdef extern from "Python.h":
     void PyErr_Clear()
     PyGILState_STATE PyGILState_Ensure()
     void PyGILState_Release(PyGILState_STATE)
+    struct PyThreadState
+    PyThreadState* PyEval_SaveThread()
+    void PyEval_RestoreThread(PyThreadState *tstate)
 
 ctypedef struct DBusError:
     char *name
@@ -438,16 +441,22 @@ cdef class Connection:
         cdef DBusError error
         cdef DBusMessage *msg
         cdef Message m
+        cdef PyThreadState *_save
+        cdef int int_timeout_milliseconds
 
         dbus_error_init(&error)
 
         msg = message._get_msg()
 
+        int_timeout_milliseconds = timeout_milliseconds
+        _save = PyEval_SaveThread()
+        # NOTE: Don't use Python code until RestoreThread
         retval = dbus_connection_send_with_reply_and_block(
             self.conn,
             msg,
-            timeout_milliseconds,
+            int_timeout_milliseconds,
             &error)
+        PyEval_RestoreThread(_save)
 
         if dbus_error_is_set(&error):
             errormsg = error.message
@@ -629,7 +638,11 @@ cdef class PendingCall:
         return message
 
     def block(self):
+        cdef PyThreadState *_save
+        _save = PyEval_SaveThread()
+        # NOTE: Don't use Python code until RestoreThread
         dbus_pending_call_block(self.pending_call)
+        PyEval_RestoreThread(_save)
 
     def set_notify(self, reply_handler, error_handler):
         user_data = (reply_handler, error_handler)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hello-slow.py
Type: text/x-python
Size: 678 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/dbus/attachments/20060802/ac8d6c97/hello-slow.py
-------------- next part --------------
A non-text attachment was scrubbed...
Name: client.py
Type: text/x-python
Size: 679 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/dbus/attachments/20060802/ac8d6c97/client.py


More information about the dbus mailing list