summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKari Oikarinen <kari.oikarinen@qt.io>2017-02-14 13:16:49 +0200
committerKari Oikarinen <kari.oikarinen@qt.io>2017-03-24 14:30:59 +0000
commitab208dd8b45792a5eeac00a4b5856dc27ee1af91 (patch)
treedacb8a7d1cc5dd81c28640de814998dddd0769d3
parent86ac7b459b580d88de8ddb6721ccfce6b4f466ae (diff)
Add ConnectionPool for Connections
Rather than directly creating the Connection inside DeviceInformationFetcher, get it from a ConnectionPool that gives an existing connection if there already is one to the device. Change connections to close upon destruction. They will be closed once last shared pointer gotten from ConnectionPool destructs. Change-Id: I44d4b11d71f8b3c5488fdb52266608bfee69c644 Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
-rw-r--r--qdb/qdb.pro2
-rw-r--r--qdb/server/connection.cpp9
-rw-r--r--qdb/server/connectionpool.cpp57
-rw-r--r--qdb/server/connectionpool.h42
-rw-r--r--qdb/server/deviceinformationfetcher.cpp22
-rw-r--r--qdb/server/deviceinformationfetcher.h5
-rw-r--r--qdb/server/devicemanager.cpp2
-rw-r--r--qdb/server/devicemanager.h2
8 files changed, 119 insertions, 22 deletions
diff --git a/qdb/qdb.pro b/qdb/qdb.pro
index b6fca45..50eef74 100644
--- a/qdb/qdb.pro
+++ b/qdb/qdb.pro
@@ -16,6 +16,7 @@ HEADERS += \
client/client.h \
hostmessages.h \
server/connection.h \
+ server/connectionpool.h \
server/deviceinformationfetcher.h \
server/devicemanager.h \
server/echoservice.h \
@@ -36,6 +37,7 @@ SOURCES += \
hostmessages.cpp \
main.cpp \
server/connection.cpp \
+ server/connectionpool.cpp \
server/deviceinformationfetcher.cpp \
server/devicemanager.cpp \
server/echoservice.cpp \
diff --git a/qdb/server/connection.cpp b/qdb/server/connection.cpp
index 2b13666..74b6486 100644
--- a/qdb/server/connection.cpp
+++ b/qdb/server/connection.cpp
@@ -50,6 +50,11 @@ Connection::Connection(QdbTransport *transport, QObject *parent)
}
+Connection::~Connection()
+{
+ close();
+}
+
void Connection::connect()
{
Q_ASSERT(m_state == ConnectionState::Disconnected);
@@ -83,6 +88,8 @@ void Connection::close()
enqueueMessage(QdbMessage{QdbMessage::Close, stream->hostId(), stream->deviceId()});
// Processing of the Close message erased the stream from m_streams
}
+
+ m_state = ConnectionState::Disconnected;
}
ConnectionState Connection::state() const
@@ -97,8 +104,6 @@ void Connection::createStream(const QByteArray &openTag, StreamCreatedCallback s
enqueueMessage(QdbMessage{QdbMessage::Open, id, 0, openTag});
}
-Connection::~Connection() = default;
-
void Connection::enqueueMessage(const QdbMessage &message)
{
Q_ASSERT(message.command() != QdbMessage::Invalid);
diff --git a/qdb/server/connectionpool.cpp b/qdb/server/connectionpool.cpp
new file mode 100644
index 0000000..4fd6e79
--- /dev/null
+++ b/qdb/server/connectionpool.cpp
@@ -0,0 +1,57 @@
+/******************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Debug Bridge.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+#include "connectionpool.h"
+
+#include "connection.h"
+#include "libqdb/protocol/qdbtransport.h"
+#include "usb-host/usbconnection.h"
+#include "usb-host/usbdevice.h"
+
+#include <QtCore/qloggingcategory.h>
+
+Q_LOGGING_CATEGORY(connectionPoolC, "qdb.connectionpool")
+
+std::shared_ptr<Connection> ConnectionPool::connect(const UsbDevice &device)
+{
+ if (m_connections.contains(device.serial)) {
+ std::shared_ptr<Connection> existingConnection = m_connections[device.serial].lock();
+ if (existingConnection) {
+ qDebug(connectionPoolC) << "Using existing connection to" << device.serial;
+ return existingConnection;
+ } else {
+ qDebug(connectionPoolC) << "Existing connection to" << device.serial << "expired, creating new one";
+ m_connections.remove(device.serial);
+ }
+ }
+
+ auto connection = std::make_shared<Connection>(new QdbTransport{new UsbConnection{device}});
+ m_connections[device.serial] = std::weak_ptr<Connection>(connection);
+
+ if (!connection->initialize()) {
+ qCCritical(connectionPoolC) << "Could not initialize connection to" << device.serial;
+ return std::shared_ptr<Connection>(nullptr);
+ }
+
+ connection->connect();
+ qCDebug(connectionPoolC) << "Initialized connection to" << device.serial;
+
+ return connection;
+}
diff --git a/qdb/server/connectionpool.h b/qdb/server/connectionpool.h
new file mode 100644
index 0000000..6d4daf3
--- /dev/null
+++ b/qdb/server/connectionpool.h
@@ -0,0 +1,42 @@
+/******************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Debug Bridge.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+#ifndef CONNECTIONPOOL_H
+#define CONNECTIONPOOL_H
+
+class Connection;
+struct UsbDevice;
+
+#include <QtCore/qhash.h>
+
+#include <memory>
+
+class ConnectionPool
+{
+public:
+ ConnectionPool() = default;
+
+ std::shared_ptr<Connection> connect(const UsbDevice &device);
+
+private:
+ QHash<QString, std::weak_ptr<Connection>> m_connections;
+};
+
+#endif // CONNECTIONPOOL_H
diff --git a/qdb/server/deviceinformationfetcher.cpp b/qdb/server/deviceinformationfetcher.cpp
index 9a85b7c..62e30c9 100644
--- a/qdb/server/deviceinformationfetcher.cpp
+++ b/qdb/server/deviceinformationfetcher.cpp
@@ -43,33 +43,23 @@ bool operator!=(const DeviceInformation &lhs, const DeviceInformation &rhs)
return !(lhs == rhs);
}
-DeviceInformationFetcher::DeviceInformationFetcher(UsbDevice device)
- : m_connection{new Connection{new QdbTransport{new UsbConnection{device}}}},
- m_deviceAddress(device.address), // uniform initialization with {} fails with GCC 4.9
- m_connected{false}
+DeviceInformationFetcher::DeviceInformationFetcher(std::shared_ptr<Connection> connection,
+ UsbDevice device)
+ : m_connection{connection},
+ m_deviceAddress(device.address) // uniform initialization with {} fails with GCC 4.9
{
- connect(this, &DeviceInformationFetcher::fetched, m_connection, &Connection::close);
- connect(this, &DeviceInformationFetcher::fetched, m_connection, &QObject::deleteLater);
- if (!m_connection->initialize()) {
- qCCritical(deviceInfoC) << "Could not initialize connection to" << device.serial << "for fetching device information";
- return;
- }
-
- m_connection->connect();
- m_connected = true;
- qCDebug(deviceInfoC) << "Initialized connection to" << device.serial;
}
void DeviceInformationFetcher::fetch()
{
- if (!m_connected) {
+ if (!m_connection || m_connection->state() == ConnectionState::Disconnected) {
qCWarning(deviceInfoC) << "Not fetching device information due to no connection";
emit fetched(DeviceInformation{"", "", "", m_deviceAddress});
return;
}
- auto *service = new HandshakeService{m_connection};
+ auto *service = new HandshakeService{m_connection.get()};
connect(this, &DeviceInformationFetcher::fetched,
service, &QObject::deleteLater);
diff --git a/qdb/server/deviceinformationfetcher.h b/qdb/server/deviceinformationfetcher.h
index efcbd17..8083ddb 100644
--- a/qdb/server/deviceinformationfetcher.h
+++ b/qdb/server/deviceinformationfetcher.h
@@ -41,7 +41,7 @@ class DeviceInformationFetcher : public QObject
{
Q_OBJECT
public:
- explicit DeviceInformationFetcher(UsbDevice device);
+ explicit DeviceInformationFetcher(std::shared_ptr<Connection> connection, UsbDevice device);
signals:
void fetched(DeviceInformation deviceInfo);
@@ -53,9 +53,8 @@ private slots:
void handshakeResponse(QString serial, QString hostMac, QString ipAddress);
private:
- Connection *m_connection; // owned by this class, deletion set up in constructor
+ std::shared_ptr<Connection> m_connection;
UsbAddress m_deviceAddress;
- bool m_connected;
};
#endif // DEVICEINFORMATIONFETCHER_H
diff --git a/qdb/server/devicemanager.cpp b/qdb/server/devicemanager.cpp
index 3314546..37a37e2 100644
--- a/qdb/server/devicemanager.cpp
+++ b/qdb/server/devicemanager.cpp
@@ -135,7 +135,7 @@ void DeviceManager::fetchDeviceInformation(UsbDevice device)
Q_ASSERT(!m_fetching);
m_fetching = true;
m_fetchingDevice = device;
- auto *fetcher = new DeviceInformationFetcher{device};
+ auto *fetcher = new DeviceInformationFetcher{m_pool.connect(device), device};
connect(fetcher, &DeviceInformationFetcher::fetched, fetcher, &QObject::deleteLater);
connect(fetcher, &DeviceInformationFetcher::fetched, this, &DeviceManager::handleDeviceInformation);
diff --git a/qdb/server/devicemanager.h b/qdb/server/devicemanager.h
index bc1036d..b839303 100644
--- a/qdb/server/devicemanager.h
+++ b/qdb/server/devicemanager.h
@@ -21,6 +21,7 @@
#ifndef DEVICEMANAGER_H
#define DEVICEMANAGER_H
+#include "connectionpool.h"
#include "deviceinformationfetcher.h"
#include "usb-host/usbdeviceenumerator.h"
@@ -55,6 +56,7 @@ private:
UsbDevice m_fetchingDevice;
bool m_fetching;
std::vector<DeviceInformation> m_deviceInfos;
+ ConnectionPool m_pool;
};
#endif // DEVICEMANAGER_H