summaryrefslogtreecommitdiff
path: root/src/syncevo/LocalTransportAgent.cpp
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2012-07-10 07:36:34 +0000
committerPatrick Ohly <patrick.ohly@intel.com>2012-07-10 09:37:25 +0000
commit9d9b6d8b57fdd22bdc20757ad537c8040116ea49 (patch)
tree54bcb3f100bd6517b7ab2d8352575471797fdc40 /src/syncevo/LocalTransportAgent.cpp
parent8654992ecaad45e69217e2398d49e31a70ae49d1 (diff)
local sync: fixed helper process shutdown in case of parent failure
The helper process only detected that the parent failed when it tried to log something while the parent had already shut down the D-Bus connection. Even that did not work reliably and differed between D-Bus libdbus and GIO. Now logging ignores failures to send the message (done the same way as in the syncevo-dbus-helper -> syncevo-dbus-server communication). Parent failures are detected via the ForkExecChild::m_onQuit signal. They set the "abort" state permanently until the helper process terminates. Found while testing some new failure test cases in combination with D-Bus libdbus.
Diffstat (limited to 'src/syncevo/LocalTransportAgent.cpp')
-rw-r--r--src/syncevo/LocalTransportAgent.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/syncevo/LocalTransportAgent.cpp b/src/syncevo/LocalTransportAgent.cpp
index 4259a267..217cfda1 100644
--- a/src/syncevo/LocalTransportAgent.cpp
+++ b/src/syncevo/LocalTransportAgent.cpp
@@ -538,7 +538,8 @@ public:
};
GDBusCXX::EmitSignal2<std::string,
- std::string> m_logOutput;
+ std::string,
+ true /* ignore transmission failures */> m_logOutput;
};
class LocalTransportAgentChild : public TransportAgent, private LoggerBase
@@ -631,6 +632,15 @@ class LocalTransportAgentChild : public TransportAgent, private LoggerBase
}
}
+ static void onParentQuit()
+ {
+ // Never free this state blocker. We can only abort and
+ // quit from now on.
+ static boost::shared_ptr<SuspendFlags::StateBlocker> abortGuard;
+ SE_LOG_ERROR(NULL, NULL, "sync parent quit unexpectedly");
+ abortGuard = SuspendFlags::getSuspendFlags().abort();
+ }
+
void onConnect(const GDBusCXX::DBusConnectionPtr &conn)
{
SE_LOG_DEBUG(NULL, NULL, "child connected to parent");
@@ -833,6 +843,17 @@ public:
m_forkexec->m_onConnect.connect(boost::bind(&LocalTransportAgentChild::onConnect, this, _1));
m_forkexec->m_onFailure.connect(boost::bind(&LocalTransportAgentChild::onFailure, this, _1, _2));
+ // When parent quits, we need to abort whatever we do and shut
+ // down. There's no way how we can complete our work without it.
+ //
+ // Note that another way how this process can detect the
+ // death of the parent is when it currently is waiting for
+ // completion of a method call to the parent, like a request
+ // for a password. However, that does not cover failures
+ // like the parent not asking us to sync in the first place
+ // and also does not work with libdbus (https://bugs.freedesktop.org/show_bug.cgi?id=49728).
+ m_forkexec->m_onQuit.connect(onParentQuit);
+
m_forkexec->connect();
}