aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-06-16 13:40:08 +0200
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-08-04 13:34:48 +0000
commita010f3a8f92a9a364e9d17d12b06074fde6f8a17 (patch)
tree33a3a91f63d8daa4a5a939a4af4e29812c803bc0 /src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
parent31291359a327c5ffa6aa3aff76b62491782408d7 (diff)
Deduplicate debug server connection code.
The packet protocol can be part of the server, now that the server is not part of QtQml anymore. This enables us to remove some duplicated code from the connections. As an added benefit, with more control over the sending process, QQmlDebugServer can now efficiently send single packets, without creating a QList<QByteArray> first. Change-Id: I13cc831e254c02b737e64816d6d3ab051d760995 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp')
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp89
1 files changed, 62 insertions, 27 deletions
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index af77e6875b..4a4af77064 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -33,6 +33,7 @@
#include "qqmldebugserver.h"
#include "qqmldebugserverfactory.h"
+#include "qpacketprotocol.h"
#include "qqmldebugserverconnection.h"
#include <private/qqmldebugservice_p.h>
@@ -101,8 +102,7 @@ public:
bool removeService(QQmlDebugService *service);
bool open(const QVariantHash &configuration);
-
- void receiveMessage(const QByteArray &message);
+ void setDevice(QIODevice *socket);
template<class Action>
bool enable(Action action);
@@ -116,6 +116,8 @@ private slots:
void sendMessages(const QString &name, const QList<QByteArray> &messages);
void changeServiceState(const QString &serviceName, QQmlDebugService::State state);
void removeThread();
+ void receiveMessage();
+ void invalidPacket();
private:
friend struct StartTcpServerAction;
@@ -139,6 +141,8 @@ private:
bool init(const QString &pluginName, bool block);
+ bool canSendMessage(const QString &name);
+ void doSendMessage(const QString &name, const QByteArray &message);
QQmlDebugServerConnection *loadConnectionPlugin(const QString &pluginName);
QQmlDebugServerConnection *m_connection;
@@ -152,6 +156,7 @@ private:
QMutex m_helloMutex;
QWaitCondition m_helloCondition;
QQmlDebugServerThread *m_thread;
+ QPacketProtocol *m_protocol;
#ifndef QT_NO_LIBRARY
QPluginLoader m_loader;
#endif
@@ -478,14 +483,17 @@ bool QQmlDebugServerImpl::enableFromArguments()
return false;
}
-void QQmlDebugServerImpl::receiveMessage(const QByteArray &message)
+void QQmlDebugServerImpl::receiveMessage()
{
typedef QHash<QString, QQmlDebugService*>::const_iterator DebugServiceConstIt;
// to be executed in debugger thread
Q_ASSERT(QThread::currentThread() == thread());
- QQmlDebugStream in(message);
+ if (!m_protocol)
+ return;
+
+ QQmlDebugStream in(m_protocol->read().data());
QString name;
@@ -523,7 +531,10 @@ void QQmlDebugServerImpl::receiveMessage(const QByteArray &message)
out << QString(QStringLiteral("QDeclarativeDebugClient")) << 0 << protocolVersion
<< pluginNames << pluginVersions << QQmlDebugStream::s_dataStreamVersion;
- m_connection->send(QList<QByteArray>() << helloAnswer);
+ QPacket pack;
+ pack.writeRawData(helloAnswer.data(), helloAnswer.length());
+ m_protocol->send(pack);
+ m_connection->flush();
QMutexLocker helloLock(&m_helloMutex);
m_gotHello = true;
@@ -558,7 +569,7 @@ void QQmlDebugServerImpl::receiveMessage(const QByteArray &message)
} else {
qWarning("QML Debugger: Invalid control message %d.", op);
- m_connection->disconnect();
+ invalidPacket();
return;
}
@@ -700,34 +711,39 @@ bool QQmlDebugServerImpl::removeService(QQmlDebugService *service)
return true;
}
-void QQmlDebugServerImpl::sendMessage(const QString &name, const QByteArray &message)
+bool QQmlDebugServerImpl::canSendMessage(const QString &name)
{
- sendMessages(name, QList<QByteArray>() << message);
+ // to be executed in debugger thread
+ Q_ASSERT(QThread::currentThread() == thread());
+ return m_connection && m_connection->isConnected() && m_protocol &&
+ m_clientPlugins.contains(name);
}
-void QQmlDebugServerImpl::sendMessages(const QString &name, const QList<QByteArray> &messages)
+void QQmlDebugServerImpl::doSendMessage(const QString &name, const QByteArray &message)
{
- // to be executed in debugger thread
- Q_ASSERT(QThread::currentThread() == thread());
+ QByteArray prefixed;
+ QQmlDebugStream out(&prefixed, QIODevice::WriteOnly);
+ out << name << message;
- if (!m_connection)
- return;
+ QPacket pack;
+ pack.writeRawData(prefixed.data(), prefixed.length());
+ m_protocol->send(pack);
+}
- if (!name.isEmpty()) {
- if (!m_clientPlugins.contains(name))
- return;
- QList<QByteArray> prefixedMessages;
- prefixedMessages.reserve(messages.count());
- foreach (const QByteArray &message, messages) {
- QByteArray prefixed;
- QQmlDebugStream out(&prefixed, QIODevice::WriteOnly);
- out << name << message;
- prefixedMessages << prefixed;
- }
+void QQmlDebugServerImpl::sendMessage(const QString &name, const QByteArray &message)
+{
+ if (canSendMessage(name)) {
+ doSendMessage(name, message);
+ m_connection->flush();
+ }
+}
- m_connection->send(prefixedMessages);
- } else {
- m_connection->send(messages);
+void QQmlDebugServerImpl::sendMessages(const QString &name, const QList<QByteArray> &messages)
+{
+ if (canSendMessage(name)) {
+ foreach (const QByteArray &message, messages)
+ doSendMessage(name, message);
+ m_connection->flush();
}
}
@@ -769,6 +785,25 @@ void QQmlDebugServerImpl::EngineCondition::wake()
Q_ASSERT_X(numServices >=0, Q_FUNC_INFO, "Woken more often than #services.");
}
+void QQmlDebugServerImpl::setDevice(QIODevice *socket)
+{
+ m_protocol = new QPacketProtocol(socket, this);
+ QObject::connect(m_protocol, SIGNAL(readyRead()), this, SLOT(receiveMessage()));
+ QObject::connect(m_protocol, SIGNAL(invalidPacket()), this, SLOT(invalidPacket()));
+
+ if (blockingMode())
+ m_protocol->waitForReadyRead(-1);
+}
+
+void QQmlDebugServerImpl::invalidPacket()
+{
+ qWarning("QML Debugger: Received a corrupted packet! Giving up ...");
+ m_connection->disconnect();
+ // protocol might still be processing packages at this point
+ m_protocol->deleteLater();
+ m_protocol = 0;
+}
+
QQmlDebugConnector *QQmlDebugServerFactory::create(const QString &key)
{
// Cannot parent it to this because it gets moved to another thread