Fix launching of shipped dbus-daemon

When using QProcess::startDetached on Windows, a console Window is
visible. Since dbus-daemon should run silently in the background,
use our customized CProcess instead which supports starting without
console.
This commit also fixes a race condition. CDBusServer launched the
dbus-daemon and immediatly tried to register. If dbus-daemon was not yet
initialized and ready to accept connections, registering the service
failed. This is fixed by a small timeout.

refs #615
This commit is contained in:
Roland Winklmeier
2016-05-05 14:04:36 +02:00
parent e12e655d70
commit df4ac9538a

View File

@@ -10,19 +10,21 @@
#include "blackmisc/dbusserver.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/network/networkutils.h"
#include "blackmisc/processctrl.h"
#include "blackmisc/statusmessage.h"
#include <QDBusServer>
#include <QMetaClassInfo>
#include <QMetaObject>
#include <QProcess>
#include <QStringList>
#include <QThread>
#include <QtGlobal>
using namespace BlackMisc::Network;
namespace BlackMisc
{
CDBusServer::CDBusServer(const QString &service, const QString &address, QObject *parent) : QObject(parent)
{
m_serverMode = modeOfAddress(address);
@@ -30,14 +32,16 @@ namespace BlackMisc
{
case SERVERMODE_SESSIONBUS:
{
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
if (! connection.isConnected())
{
launchDBusDaemon();
connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
}
QDBusConnection testConnection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
if (! testConnection.isConnected()) { launchDBusDaemon(); }
testConnection.disconnectFromBus(coreServiceName());
if (! connection.registerService(service))
// Sleep for 200 ms in order for dbus-daemon to finish loading.
// FIXME: Dirty workaround. Instead poll the the server up to x times every 50 ms until it connection is accepted.
QThread::msleep(200);
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
if (! connection.isConnected() || ! connection.registerService(service))
{
// registration fails can either mean something wrong with DBus or service already exists
CLogMessage(this).warning("DBus registration: %1") << connection.lastError().message();
@@ -47,14 +51,15 @@ namespace BlackMisc
break;
case SERVERMODE_SYSTEMBUS:
{
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SystemBus, coreServiceName());
if (!connection.isConnected())
{
launchDBusDaemon();
connection = QDBusConnection::connectToBus(QDBusConnection::SystemBus, coreServiceName());
}
QDBusConnection testConnection = QDBusConnection::connectToBus(QDBusConnection::SystemBus, coreServiceName());
if (! testConnection.isConnected()) { launchDBusDaemon(); }
testConnection.disconnectFromBus(coreServiceName());
if (!connection.registerService(service))
// Sleep for 200 ms in order for dbus-daemon to finish loading.
QThread::msleep(200);
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SystemBus, coreServiceName());
if (! connection.isConnected() || ! connection.registerService(service))
{
// registration fails can either mean something wrong with DBus or service already exists
CLogMessage(this).warning("DBus registration: %1") << connection.lastError().message();
@@ -103,7 +108,7 @@ namespace BlackMisc
{
const QString program = QStringLiteral("dbus-daemon");
const QStringList arguments = { QStringLiteral("--config-file=../etc/dbus-1/session.conf") };
bool success = QProcess::startDetached(program, arguments);
bool success = CProcessCtrl::startDetachedWithoutConsole(program, arguments);
if (!success) { CLogMessage(this).error("Failed to launch dbus-daemon!"); }
}