diff options
author | Simon McVittie <smcv@collabora.com> | 2019-09-02 14:41:11 +0100 |
---|---|---|
committer | Simon McVittie <smcv@collabora.com> | 2019-09-02 14:42:58 +0100 |
commit | dbc0f7ef463922c026f1183a07368aa61ffe98dc (patch) | |
tree | 04aaedd4fdf56827a4e0e6fe71a9190648ca48e2 | |
parent | 5e3a97992b206037c137a8cfda1a2c2f18fac45a (diff) | |
download | dbus-python-dbc0f7ef463922c026f1183a07368aa61ffe98dc.tar.gz |
Consistently save/restore exception indicator when called from C code
Signed-off-by: Simon McVittie <smcv@collabora.com>
-rw-r--r-- | dbus_bindings/conn-methods.c | 34 | ||||
-rw-r--r-- | dbus_bindings/pending-call.c | 14 | ||||
-rw-r--r-- | dbus_bindings/server.c | 11 |
3 files changed, 43 insertions, 16 deletions
diff --git a/dbus_bindings/conn-methods.c b/dbus_bindings/conn-methods.c index 62bdf86..ddd0766 100644 --- a/dbus_bindings/conn-methods.c +++ b/dbus_bindings/conn-methods.c @@ -34,9 +34,12 @@ static void _object_path_unregister(DBusConnection *conn, void *user_data) { PyGILState_STATE gil = PyGILState_Ensure(); + PyObject *et, *ev, *tb; PyObject *tuple = NULL; Connection *conn_obj = NULL; - PyObject *callable; + PyObject *callable = NULL; + + PyErr_Fetch(&et, &ev, &tb); conn_obj = (Connection *)DBusPyConnection_ExistingFromDBusConnection(conn); if (!conn_obj) goto out; @@ -59,13 +62,15 @@ _object_path_unregister(DBusConnection *conn, void *user_data) Py_XDECREF(PyObject_CallFunctionObjArgs(callable, conn_obj, NULL)); } out: + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(callable); + } + Py_CLEAR(conn_obj); Py_CLEAR(tuple); /* the user_data (a Python str) is no longer ref'd by the DBusConnection */ Py_CLEAR(user_data); - if (PyErr_Occurred()) { - PyErr_Print(); - } + PyErr_Restore(et, ev, tb); PyGILState_Release(gil); } @@ -75,10 +80,13 @@ _object_path_message(DBusConnection *conn, DBusMessage *message, { DBusHandlerResult ret; PyGILState_STATE gil = PyGILState_Ensure(); + PyObject *et, *ev, *tb; Connection *conn_obj = NULL; PyObject *tuple = NULL; PyObject *msg_obj; - PyObject *callable; /* borrowed */ + PyObject *callable = NULL; /* borrowed */ + + PyErr_Fetch(&et, &ev, &tb); dbus_message_ref(message); msg_obj = DBusPyMessage_ConsumeDBusMessage(message); @@ -123,12 +131,14 @@ _object_path_message(DBusConnection *conn, DBusMessage *message, } out: + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(callable); + } + Py_CLEAR(msg_obj); Py_CLEAR(conn_obj); Py_CLEAR(tuple); - if (PyErr_Occurred()) { - PyErr_Print(); - } + PyErr_Restore(et, ev, tb); PyGILState_Release(gil); return ret; } @@ -143,6 +153,7 @@ _filter_message(DBusConnection *conn, DBusMessage *message, void *user_data) { DBusHandlerResult ret; PyGILState_STATE gil = PyGILState_Ensure(); + PyObject *et, *ev, *tb; Connection *conn_obj = NULL; PyObject *callable = NULL; PyObject *msg_obj; @@ -150,6 +161,8 @@ _filter_message(DBusConnection *conn, DBusMessage *message, void *user_data) Py_ssize_t i, size; #endif + PyErr_Fetch(&et, &ev, &tb); + dbus_message_ref(message); msg_obj = DBusPyMessage_ConsumeDBusMessage(message); if (!msg_obj) { @@ -201,9 +214,14 @@ _filter_message(DBusConnection *conn, DBusMessage *message, void *user_data) ret = DBusPyConnection_HandleMessage(conn_obj, msg_obj, callable); out: + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(callable); + } + Py_CLEAR(msg_obj); Py_CLEAR(conn_obj); Py_CLEAR(callable); + PyErr_Restore(et, ev, tb); PyGILState_Release(gil); return ret; } diff --git a/dbus_bindings/pending-call.c b/dbus_bindings/pending-call.c index 636095f..50b2998 100644 --- a/dbus_bindings/pending-call.c +++ b/dbus_bindings/pending-call.c @@ -79,15 +79,20 @@ _pending_call_notify_function(DBusPendingCall *pc, PyObject *list) { PyGILState_STATE gil = PyGILState_Ensure(); + PyObject *et, *ev, *tb; + PyObject *handler; + DBusMessage *msg; + + PyErr_Fetch(&et, &ev, &tb); + /* BEGIN CRITICAL SECTION * While holding the GIL, make sure the callback only gets called once * by deleting it from the 1-item list that's held by libdbus. */ - PyObject *handler = PyList_GetItem(list, 0); - DBusMessage *msg; + handler = PyList_GetItem(list, 0); if (!handler) { - PyErr_Print(); + PyErr_WriteUnraisable(list); goto release; } if (handler == Py_None) { @@ -113,7 +118,7 @@ _pending_call_notify_function(DBusPendingCall *pc, PyObject *ret = PyObject_CallFunctionObjArgs(handler, msg_obj, NULL); if (!ret) { - PyErr_Print(); + PyErr_WriteUnraisable(handler); } Py_CLEAR(ret); Py_CLEAR(msg_obj); @@ -124,6 +129,7 @@ _pending_call_notify_function(DBusPendingCall *pc, release: Py_CLEAR(handler); + PyErr_Restore(et, ev, tb); PyGILState_Release(gil); } diff --git a/dbus_bindings/server.c b/dbus_bindings/server.c index dfbfa53..2080d6b 100644 --- a/dbus_bindings/server.c +++ b/dbus_bindings/server.c @@ -190,9 +190,12 @@ DBusPyServer_new_connection_cb(DBusServer *server, void *data UNUSED) { PyGILState_STATE gil = PyGILState_Ensure(); + PyObject *et, *ev, *tb; PyObject *self = NULL; PyObject *method = NULL; + PyErr_Fetch(&et, &ev, &tb); + self = DBusPyServer_ExistingFromDBusServer(server); if (!self) goto out; TRACE(self); @@ -224,12 +227,12 @@ DBusPyServer_new_connection_cb(DBusServer *server, } out: - Py_CLEAR(method); - Py_CLEAR(self); - if (PyErr_Occurred()) - PyErr_Print(); + PyErr_WriteUnraisable(method); + Py_CLEAR(self); + Py_CLEAR(method); + PyErr_Restore(et, ev, tb); PyGILState_Release(gil); } |