summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2019-09-02 14:41:11 +0100
committerSimon McVittie <smcv@collabora.com>2019-09-02 14:42:58 +0100
commitdbc0f7ef463922c026f1183a07368aa61ffe98dc (patch)
tree04aaedd4fdf56827a4e0e6fe71a9190648ca48e2
parent5e3a97992b206037c137a8cfda1a2c2f18fac45a (diff)
downloaddbus-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.c34
-rw-r--r--dbus_bindings/pending-call.c14
-rw-r--r--dbus_bindings/server.c11
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);
}