mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-05 01:05:34 +08:00
refs #883, improved detection if core is running
* use proxy to really ping core (not only checking connection) * avoid closing Qt default connections -> crash * some refactoring
This commit is contained in:
committed by
Mathew Sutcliffe
parent
d918ee4cfd
commit
6c72f8491c
@@ -9,10 +9,10 @@
|
|||||||
|
|
||||||
#include "blackcore/context/contextapplicationproxy.h"
|
#include "blackcore/context/contextapplicationproxy.h"
|
||||||
#include "blackmisc/dbus.h"
|
#include "blackmisc/dbus.h"
|
||||||
|
#include "blackmisc/dbusserver.h"
|
||||||
#include "blackmisc/genericdbusinterface.h"
|
#include "blackmisc/genericdbusinterface.h"
|
||||||
#include "blackmisc/identifierlist.h"
|
#include "blackmisc/identifierlist.h"
|
||||||
#include "blackmisc/loghandler.h"
|
#include "blackmisc/loghandler.h"
|
||||||
#include "blackmisc/settingscache.h"
|
|
||||||
|
|
||||||
#include <QDBusConnection>
|
#include <QDBusConnection>
|
||||||
#include <QLatin1Literal>
|
#include <QLatin1Literal>
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
using namespace BlackMisc;
|
using namespace BlackMisc;
|
||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
namespace Context
|
namespace Context
|
||||||
@@ -179,5 +180,28 @@ namespace BlackCore
|
|||||||
if (fileName.isEmpty()) { return false; }
|
if (fileName.isEmpty()) { return false; }
|
||||||
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("existsFile"), fileName);
|
return this->m_dBusInterface->callDBusRet<bool>(QLatin1Literal("existsFile"), fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CContextApplicationProxy::isContextResponsive(const QString &dBusAddress, QString &msg, int timeoutMs)
|
||||||
|
{
|
||||||
|
const bool connected = CDBusServer::isDBusAvailable(dBusAddress, msg, timeoutMs);
|
||||||
|
if (!connected) { return false; }
|
||||||
|
|
||||||
|
static const QString dBusName("contexttest");
|
||||||
|
QDBusConnection connection = CDBusServer::connectToDBus(dBusAddress, dBusName);
|
||||||
|
CContextApplicationProxy proxy(BlackMisc::CDBusServer::coreServiceName(), connection, CCoreFacadeConfig::Remote, nullptr);
|
||||||
|
const CIdentifier id("swift proxy test");
|
||||||
|
const CIdentifier pingId = proxy.registerApplication(id);
|
||||||
|
const bool ok = (id == pingId);
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
proxy.unregisterApplication(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg = "Mismatch in proxy ping, context not ready.";
|
||||||
|
}
|
||||||
|
CDBusServer::disconnectFromDBus(connection, dBusAddress);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -74,6 +74,11 @@ namespace BlackCore
|
|||||||
virtual bool existsFile(const QString &fileName) const override;
|
virtual bool existsFile(const QString &fileName) const override;
|
||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
|
//! Used to test if there is a core running?
|
||||||
|
//! \note creates and connects via proxy object, so not meant for very frequent tests
|
||||||
|
//! \sa CDBusServer::isDBusAvailable as lightweight, but less accurate alternative
|
||||||
|
static bool isContextResponsive(const QString &dbusAddress, QString &msg, int timeoutMs = 1500);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CContextApplicationProxy(CCoreFacadeConfig::ContextMode mode, CCoreFacade *runtime) : IContextApplication(mode, runtime), m_dBusInterface(nullptr) {}
|
CContextApplicationProxy(CCoreFacadeConfig::ContextMode mode, CCoreFacade *runtime) : IContextApplication(mode, runtime), m_dBusInterface(nullptr) {}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace BlackMisc
|
|||||||
testConnection.disconnectFromBus(coreServiceName());
|
testConnection.disconnectFromBus(coreServiceName());
|
||||||
|
|
||||||
// Sleep for 200 ms in order for dbus-daemon to finish loading.
|
// 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.
|
// FIXME: Dirty workaround. Instead polling the server up to x times every 50 ms until its connection is accepted.
|
||||||
QThread::msleep(200);
|
QThread::msleep(200);
|
||||||
|
|
||||||
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
|
QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, coreServiceName());
|
||||||
@@ -122,7 +122,7 @@ namespace BlackMisc
|
|||||||
if (address.contains("host=") || address.contains("port="))
|
if (address.contains("host=") || address.contains("port="))
|
||||||
{
|
{
|
||||||
// "tcp:host=foo.com,port=123"
|
// "tcp:host=foo.com,port=123"
|
||||||
QStringList parts(address.split(','));
|
const QStringList parts(address.split(','));
|
||||||
for (const QString &part : parts)
|
for (const QString &part : parts)
|
||||||
{
|
{
|
||||||
if (part.startsWith("host="))
|
if (part.startsWith("host="))
|
||||||
@@ -148,6 +148,12 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CDBusServer::isQtDefaultConnection(const QDBusConnection &connection)
|
||||||
|
{
|
||||||
|
return connection.name() == QDBusConnection::sessionBus().name() ||
|
||||||
|
connection.name() == QDBusConnection::systemBus().name();
|
||||||
|
}
|
||||||
|
|
||||||
bool CDBusServer::isQtDBusAddress(const QString &address)
|
bool CDBusServer::isQtDBusAddress(const QString &address)
|
||||||
{
|
{
|
||||||
return address.startsWith("tcp:") || address.startsWith("unix:");
|
return address.startsWith("tcp:") || address.startsWith("unix:");
|
||||||
@@ -300,6 +306,39 @@ namespace BlackMisc
|
|||||||
return system;
|
return system;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDBusConnection CDBusServer::connectToDBus(const QString &dBusAddress, const QString &name)
|
||||||
|
{
|
||||||
|
if (dBusAddress == sessionBusAddress())
|
||||||
|
{
|
||||||
|
if (name.isEmpty()) return QDBusConnection::sessionBus();
|
||||||
|
return QDBusConnection::connectToBus(QDBusConnection::SessionBus, name);
|
||||||
|
}
|
||||||
|
else if (dBusAddress == systemBusAddress())
|
||||||
|
{
|
||||||
|
if (name.isEmpty()) return QDBusConnection::systemBus();
|
||||||
|
return QDBusConnection::connectToBus(QDBusConnection::SystemBus, name);
|
||||||
|
}
|
||||||
|
else if (isP2PAddress(dBusAddress))
|
||||||
|
{
|
||||||
|
return QDBusConnection::connectToPeer(dBusAddress,
|
||||||
|
name.isEmpty() ? CDBusServer::p2pConnectionName() : name);
|
||||||
|
}
|
||||||
|
return QDBusConnection("invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDBusServer::disconnectFromDBus(const QDBusConnection &connection, const QString &dBusAddress)
|
||||||
|
{
|
||||||
|
if (CDBusServer::isQtDefaultConnection(connection)) return; // do not touch the default connections
|
||||||
|
if (CDBusServer::isP2PAddress(dBusAddress))
|
||||||
|
{
|
||||||
|
QDBusConnection::disconnectFromPeer(connection.name());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QDBusConnection::disconnectFromBus(connection.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString CDBusServer::p2pAddress(const QString &host, const QString &port)
|
QString CDBusServer::p2pAddress(const QString &host, const QString &port)
|
||||||
{
|
{
|
||||||
QString h = host.trimmed().toLower().remove(' ');
|
QString h = host.trimmed().toLower().remove(' ');
|
||||||
@@ -329,7 +368,7 @@ namespace BlackMisc
|
|||||||
// 192.168.5.3:9300 style
|
// 192.168.5.3:9300 style
|
||||||
if (h.contains(":"))
|
if (h.contains(":"))
|
||||||
{
|
{
|
||||||
QStringList parts = h.split(":");
|
const QStringList parts = h.split(":");
|
||||||
h = parts.at(0).trimmed();
|
h = parts.at(0).trimmed();
|
||||||
p = parts.at(1).trimmed();
|
p = parts.at(1).trimmed();
|
||||||
}
|
}
|
||||||
@@ -344,6 +383,12 @@ namespace BlackMisc
|
|||||||
return QString("tcp:host=%1,port=%2").arg(h).arg(p);
|
return QString("tcp:host=%1,port=%2").arg(h).arg(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString &CDBusServer::p2pConnectionName()
|
||||||
|
{
|
||||||
|
static const QString n("p2pConnection");
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
QString CDBusServer::normalizeAddress(const QString &address)
|
QString CDBusServer::normalizeAddress(const QString &address)
|
||||||
{
|
{
|
||||||
const QString lc(address.toLower().trimmed());
|
const QString lc(address.toLower().trimmed());
|
||||||
@@ -355,7 +400,7 @@ namespace BlackMisc
|
|||||||
if (lc.startsWith("sys")) { return systemBusAddress(); }
|
if (lc.startsWith("sys")) { return systemBusAddress(); }
|
||||||
if (lc.startsWith("ses")) { return sessionBusAddress(); }
|
if (lc.startsWith("ses")) { return sessionBusAddress(); }
|
||||||
|
|
||||||
// Qt / p2p
|
// Qt / P2P
|
||||||
if (isQtDBusAddress(address)) { return address; }
|
if (isQtDBusAddress(address)) { return address; }
|
||||||
return p2pAddress(address);
|
return p2pAddress(address);
|
||||||
}
|
}
|
||||||
@@ -374,41 +419,28 @@ namespace BlackMisc
|
|||||||
return CNetworkUtils::canConnect(address, port, unused, timeoutMs);
|
return CNetworkUtils::canConnect(address, port, unused, timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDBusServer::isDBusAvailable(const QString &address, int port, QString &o_message, int timeoutMs)
|
bool CDBusServer::isDBusAvailable(const QString &address, int port, QString &message, int timeoutMs)
|
||||||
{
|
{
|
||||||
return CNetworkUtils::canConnect(address, port, o_message, timeoutMs);
|
return CNetworkUtils::canConnect(address, port, message, timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDBusServer::isDBusAvailable(const QString &dbusAddress, QString &o_message, int timeoutMs)
|
bool CDBusServer::isDBusAvailable(const QString &dBusAddress, QString &message, int timeoutMs)
|
||||||
{
|
{
|
||||||
if (dbusAddress.isEmpty()) { o_message = "no address"; return false; }
|
if (dBusAddress.isEmpty()) { message = "No address."; return false; }
|
||||||
if (isP2PAddress(dbusAddress))
|
if (isP2PAddress(dBusAddress))
|
||||||
{
|
{
|
||||||
QString host;
|
QString host;
|
||||||
int port = -1;
|
int port = -1;
|
||||||
if (dBusAddressToHostAndPort(dbusAddress, host, port))
|
return CDBusServer::dBusAddressToHostAndPort(dBusAddress, host, port) ?
|
||||||
{
|
CDBusServer::isDBusAvailable(host, port, message, timeoutMs) :
|
||||||
return isDBusAvailable(host, port, o_message, timeoutMs);
|
false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString name = coreServiceName();
|
QDBusConnection connection = CDBusServer::connectToDBus(dBusAddress);
|
||||||
QDBusConnection connection = dbusAddress == systemBusAddress() ?
|
const bool isConnected = connection.isConnected();
|
||||||
QDBusConnection::connectToBus(QDBusConnection::SystemBus, name) :
|
message = connection.lastError().message();
|
||||||
QDBusConnection::connectToBus(QDBusConnection::SessionBus, name);
|
CDBusServer::disconnectFromDBus(connection, dBusAddress);
|
||||||
|
|
||||||
// todo: further checks would need to go here
|
|
||||||
// failing session bus not detected yet
|
|
||||||
|
|
||||||
o_message = connection.lastError().message();
|
|
||||||
bool isConnected = connection.isConnected();
|
|
||||||
|
|
||||||
QDBusConnection::disconnectFromBus(name);
|
|
||||||
return isConnected;
|
return isConnected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -416,6 +448,6 @@ namespace BlackMisc
|
|||||||
bool CDBusServer::isDBusAvailable(const QString &dbusAddress, int timeoutMs)
|
bool CDBusServer::isDBusAvailable(const QString &dbusAddress, int timeoutMs)
|
||||||
{
|
{
|
||||||
QString unused;
|
QString unused;
|
||||||
return isDBusAvailable(dbusAddress, unused, timeoutMs);
|
return CDBusServer::isDBusAvailable(dbusAddress, unused, timeoutMs);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -85,11 +85,20 @@ namespace BlackMisc
|
|||||||
//! Address denoting a system bus server
|
//! Address denoting a system bus server
|
||||||
static const QString &systemBusAddress();
|
static const QString &systemBusAddress();
|
||||||
|
|
||||||
|
//! Connect to DBus
|
||||||
|
static QDBusConnection connectToDBus(const QString &dbusAddress, const QString &name = {});
|
||||||
|
|
||||||
|
//! Disconnect from Bus/Peer to peer
|
||||||
|
static void disconnectFromDBus(const QDBusConnection &connection, const QString &dBusAddress);
|
||||||
|
|
||||||
//! Address denoting a P2P server at the given host and port.
|
//! Address denoting a P2P server at the given host and port.
|
||||||
//! \remarks Port number may be embedding in the host string after a colon.
|
//! \remarks Port number may be embedding in the host string after a colon.
|
||||||
//! \return p2p address like "tcp:host=foo.bar.com,port=1234"
|
//! \return p2p address like "tcp:host=foo.bar.com,port=1234"
|
||||||
static QString p2pAddress(const QString &host, const QString &port = "");
|
static QString p2pAddress(const QString &host, const QString &port = "");
|
||||||
|
|
||||||
|
//! P2P connection name
|
||||||
|
static const QString &p2pConnectionName();
|
||||||
|
|
||||||
//! Turn something like 127.0.0.1:45000 into "tcp:host=127.0.0.1,port=45000"
|
//! Turn something like 127.0.0.1:45000 into "tcp:host=127.0.0.1,port=45000"
|
||||||
//! \note Handles also "session" and "system" as valid address while CDBusServer::p2pAddress is for
|
//! \note Handles also "session" and "system" as valid address while CDBusServer::p2pAddress is for
|
||||||
//! P2P addresses only.
|
//! P2P addresses only.
|
||||||
@@ -110,11 +119,15 @@ namespace BlackMisc
|
|||||||
//! Extract host and port from a DBus address
|
//! Extract host and port from a DBus address
|
||||||
static bool dBusAddressToHostAndPort(QString dbusAddress, QString &o_host, int &o_port);
|
static bool dBusAddressToHostAndPort(QString dbusAddress, QString &o_host, int &o_port);
|
||||||
|
|
||||||
|
//! Is the given connection one of the default connections?
|
||||||
|
static bool isQtDefaultConnection(const QDBusConnection &connection);
|
||||||
|
|
||||||
//! Is there a DBus server running at the given address?
|
//! Is there a DBus server running at the given address?
|
||||||
|
//! \note This is an incomplete test showing too optimistic results for session DBus
|
||||||
//! @{
|
//! @{
|
||||||
static bool isDBusAvailable(const QString &host, int port, int timeoutMs = 1500);
|
static bool isDBusAvailable(const QString &host, int port, int timeoutMs = 1500);
|
||||||
static bool isDBusAvailable(const QString &host, int port, QString &o_message, int timeoutMs = 1500);
|
static bool isDBusAvailable(const QString &host, int port, QString &message, int timeoutMs = 1500);
|
||||||
static bool isDBusAvailable(const QString &dbusAddress, QString &o_message, int timeoutMs = 1500);
|
static bool isDBusAvailable(const QString &dbusAddress, QString &message, int timeoutMs = 1500);
|
||||||
static bool isDBusAvailable(const QString &dbusAddress, int timeoutMs = 1500);
|
static bool isDBusAvailable(const QString &dbusAddress, int timeoutMs = 1500);
|
||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user