diff options
author | John (J5) Palmieri <johnp@redhat.com> | 2005-08-31 02:18:43 +0000 |
---|---|---|
committer | John (J5) Palmieri <johnp@redhat.com> | 2005-08-31 02:18:43 +0000 |
commit | 1ea5d42dc058044af3a9ba4b9da62bf4569d54b5 (patch) | |
tree | 83100236e6c68dfa6eca0a1b3a209b7db772a0ef | |
parent | 46a1e648fe1c86dc33df799fddf97659ddc17063 (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-- | ChangeLog | 13 | ||||
-rw-r--r-- | python/dbus_bindings.pyx | 110 |
2 files changed, 78 insertions, 45 deletions
@@ -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) |