diff options
author | Kari Oikarinen <kari.oikarinen@qt.io> | 2017-02-14 13:16:49 +0200 |
---|---|---|
committer | Kari Oikarinen <kari.oikarinen@qt.io> | 2017-03-24 14:30:59 +0000 |
commit | ab208dd8b45792a5eeac00a4b5856dc27ee1af91 (patch) | |
tree | dacb8a7d1cc5dd81c28640de814998dddd0769d3 /qdb | |
parent | 86ac7b459b580d88de8ddb6721ccfce6b4f466ae (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>
Diffstat (limited to 'qdb')
-rw-r--r-- | qdb/qdb.pro | 2 | ||||
-rw-r--r-- | qdb/server/connection.cpp | 9 | ||||
-rw-r--r-- | qdb/server/connectionpool.cpp | 57 | ||||
-rw-r--r-- | qdb/server/connectionpool.h | 42 | ||||
-rw-r--r-- | qdb/server/deviceinformationfetcher.cpp | 22 | ||||
-rw-r--r-- | qdb/server/deviceinformationfetcher.h | 5 | ||||
-rw-r--r-- | qdb/server/devicemanager.cpp | 2 | ||||
-rw-r--r-- | qdb/server/devicemanager.h | 2 |
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 |