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)  | 
