* 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.
This commit is contained in:
John (J5) Palmieri 2005-08-31 02:18:43 +00:00
parent 46a1e648fe
commit 1ea5d42dc0
2 changed files with 78 additions and 45 deletions

View file

@ -1,3 +1,16 @@
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

View file

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