GDBus GIO: ensure that there is always a reply to a D-Bus method call

Now DBusResult itself tracks whether a reply was sent. If not, it
reports a generic "processing the method call failed" error. If that
error is not good enough for the method implementation, then it must
call failed() itself, as before.
This commit is contained in:
Patrick Ohly 2012-09-13 17:05:57 +02:00
parent 88169d2164
commit 11f9d90ba2

View file

@ -2184,9 +2184,11 @@ class DBusResult : virtual public Result
protected: protected:
DBusConnectionPtr m_conn; /**< connection via which the message was received */ DBusConnectionPtr m_conn; /**< connection via which the message was received */
DBusMessagePtr m_msg; /**< the method invocation message */ DBusMessagePtr m_msg; /**< the method invocation message */
bool m_replied; /**< a response was sent */
void sendMsg(const DBusMessagePtr &msg) void sendMsg(const DBusMessagePtr &msg)
{ {
m_replied = true;
GError *error = NULL; GError *error = NULL;
if (!g_dbus_connection_send_message(m_conn.get(), msg.get(), if (!g_dbus_connection_send_message(m_conn.get(), msg.get(),
G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) { G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) {
@ -2198,9 +2200,23 @@ class DBusResult : virtual public Result
DBusResult(GDBusConnection *conn, DBusResult(GDBusConnection *conn,
GDBusMessage *msg) : GDBusMessage *msg) :
m_conn(conn, true), m_conn(conn, true),
m_msg(msg, true) m_msg(msg, true),
m_replied(false)
{} {}
~DBusResult()
{
if (!m_replied) {
try {
failed(dbus_error("org.syncevolution.gdbus", "processing the method call failed"));
} catch (...) {
// Ignore failure, we are probably shutting down
// anyway, which will tell the caller that the
// method won't be processed.
}
}
}
virtual void failed(const dbus_error &error) virtual void failed(const dbus_error &error)
{ {
DBusMessagePtr errMsg(g_dbus_message_new_method_error(m_msg.get(), error.dbusName().c_str(), DBusMessagePtr errMsg(g_dbus_message_new_method_error(m_msg.get(), error.dbusName().c_str(),