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.
This commit is contained in:
Patrick Ohly 2012-07-10 07:36:34 +00:00
parent 8654992eca
commit 9d9b6d8b57
1 changed files with 22 additions and 1 deletions

View File

@ -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();
}