diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2012-07-10 07:36:34 +0000 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2012-07-10 09:37:25 +0000 |
commit | 9d9b6d8b57fdd22bdc20757ad537c8040116ea49 (patch) | |
tree | 54bcb3f100bd6517b7ab2d8352575471797fdc40 /src/syncevo/LocalTransportAgent.cpp | |
parent | 8654992ecaad45e69217e2398d49e31a70ae49d1 (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.cpp | 23 |
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(); } |