summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn (J5) Palmieri <johnp@redhat.com>2005-08-31 02:18:43 +0000
committerJohn (J5) Palmieri <johnp@redhat.com>2005-08-31 02:18:43 +0000
commit1ea5d42dc058044af3a9ba4b9da62bf4569d54b5 (patch)
tree83100236e6c68dfa6eca0a1b3a209b7db772a0ef
parent46a1e648fe1c86dc33df799fddf97659ddc17063 (diff)
* python/dbus_bindings.pyx
(_pending_call_notification, cunregister_function_handler, cmessage_function_handler): All callback functions have been rearranged to workaround a bug in Pyrex when working with the GIL which is Python's global lock when dealing with threads. They have been split into a wrapper function (which assumes the name of the old function) and a _GIL_safe_<function name> function which contains the functionality of the old function. This ensures that Pyrex does not write code the lock is released.
-rw-r--r--ChangeLog13
-rw-r--r--python/dbus_bindings.pyx110
2 files changed, 78 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index c36be7ee..de2b50b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2005-08-30 John (J5) Palmieri <johnp@redhat.com>
+ * python/dbus_bindings.pyx
+ (_pending_call_notification, cunregister_function_handler,
+ cmessage_function_handler): All callback functions have been rearranged
+ to workaround a bug in Pyrex when working with the GIL which is Python's
+ global lock when dealing with threads. They have been split into
+ a wrapper function (which assumes the name of the old function) and
+ a _GIL_safe_<function name> function which contains the functionality
+ of the old function. This ensures that Pyrex does not write code
+ the lock is released.
+
+
+2005-08-30 John (J5) Palmieri <johnp@redhat.com>
+
* python/dbus_bindings.pyx (_pending_call_notification): Obtain the
GIL global lock when calling back into Python
diff --git a/python/dbus_bindings.pyx b/python/dbus_bindings.pyx
index 6973944a..2871ae8c 100644
--- a/python/dbus_bindings.pyx
+++ b/python/dbus_bindings.pyx
@@ -178,52 +178,67 @@ cdef class PendingCall
cdef class Watch
cdef class MessageIter
+cdef void _GIL_safe_cunregister_function_handler (DBusConnection *connection,
+ void *user_data):
+ cdef Connection conn
+
+ itup = <object>user_data
+ assert (type(tup) == list)
+ function = tup[1]
+ conn = Connection()
+ conn.__cinit__(None, connection)
+
+ args = (conn)
+ function(*args)
+
cdef void cunregister_function_handler (DBusConnection *connection,
void *user_data):
- cdef Connection conn
cdef PyGILState_STATE gil
-
gil = PyGILState_Ensure()
try:
- itup = <object>user_data
- assert (type(tup) == list)
- function = tup[1]
- conn = Connection()
- conn.__cinit__(None, connection)
-
- args = [conn]
- function(*args)
+ _GIL_safe_cunregister_function_handler (connection, user_data);
finally:
PyGILState_Release(gil)
-cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
+
+
+cdef DBusHandlerResult _GIL_safe_cmessage_function_handler (
+ DBusConnection *connection,
DBusMessage *msg,
void *user_data):
cdef Connection conn
cdef Message message
- cdef PyGILState_STATE gil
+ tup = <object>user_data
+ assert (type(tup) == list)
+ function = tup[0]
+ message = EmptyMessage()
+
+ #we don't own the message so we need to ref it
+ dbus_message_ref(msg)
+ message._set_msg(msg)
+ conn = Connection()
+ conn.__cinit__(None, connection)
+ args = (conn,
+ message)
+
+ retval = function(*args)
+
+ if (retval == None):
+ retval = DBUS_HANDLER_RESULT_HANDLED
+ return retval
+
+cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
+ DBusMessage *msg,
+ void *user_data):
+ cdef PyGILState_STATE gil
gil = PyGILState_Ensure()
try:
- tup = <object>user_data
- assert (type(tup) == list)
- function = tup[0]
- message = EmptyMessage()
-
- #we don't own the message so we need to ref it
- dbus_message_ref(msg)
- message._set_msg(msg)
- conn = Connection()
- conn.__cinit__(None, connection)
- args = [conn,
- message]
- retval = function(*args)
- if (retval == None):
- retval = DBUS_HANDLER_RESULT_HANDLED
- return retval
+ return _GIL_safe_cmessage_function_handler (connection, msg, user_data);
finally:
PyGILState_Release(gil)
+
cdef class Connection:
def __init__(self, address=None, Connection _conn=None):
cdef DBusConnection *c_conn
@@ -487,11 +502,11 @@ cdef class Connection:
return child_entries
-cdef void _pending_call_notification(DBusPendingCall *pending_call, void *user_data):
+cdef void _GIL_safe_pending_call_notification (DBusPendingCall *pending_call,
+ void *user_data):
cdef DBusMessage *dbus_message
cdef Message message
- cdef PyGILState_STATE gil
-
+
(reply_handler, error_handler) = <object>user_data
dbus_message = dbus_pending_call_steal_reply(pending_call)
@@ -500,25 +515,30 @@ cdef void _pending_call_notification(DBusPendingCall *pending_call, void *user_d
type = message.get_type()
- gil = PyGILState_Ensure()
- try:
- if type == MESSAGE_TYPE_METHOD_RETURN:
- args = message.get_args_list()
- reply_handler(*args)
- elif type == MESSAGE_TYPE_ERROR:
- args = message.get_args_list()
- if len(args) > 0:
- error_handler(DBusException(args[0]))
- else:
- error_handler(DBusException(""))
+ if type == MESSAGE_TYPE_METHOD_RETURN:
+ args = message.get_args_list()
+ reply_handler(*args)
+ elif type == MESSAGE_TYPE_ERROR:
+ args = message.get_args_list()
+ if len(args) > 0:
+ error_handler(DBusException(args[0]))
else:
- error_handler(DBusException('Unexpected Message Type: ' + message.type_to_name(type)))
- finally:
- PyGILState_Release(gil)
+ error_handler(DBusException(""))
+ else:
+ error_handler(DBusException('Unexpected Message Type: ' + message.type_to_name(type)))
dbus_message_unref(dbus_message)
dbus_pending_call_unref(pending_call)
+cdef void _pending_call_notification(DBusPendingCall *pending_call,
+ void *user_data):
+ cdef PyGILState_STATE gil
+ gil = PyGILState_Ensure()
+ try:
+ _GIL_safe_pending_call_notification (pending_call, user_data);
+ finally:
+ PyGILState_Release(gil)
+
cdef void _pending_call_free_user_data(void *data):
call_tuple = <object>data
Py_XDECREF(call_tuple)