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:
parent
8654992eca
commit
9d9b6d8b57
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue