From 01bce9f3329ba617c2bd53601f4a4abbe2cb5d44 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 9 Aug 2018 12:32:56 +0200 Subject: QBluetoothServiceInfo - disentangle q<->d madness Having d_ptr as a shared pointer in a copyable q-object, and a q_ptr in this d-object was probably the dumbest idea ever, not sure how this happened at all. Task-number: QTBUG-69857 Change-Id: I845394604d42879ca36f0b376ba94819e223df77 Reviewed-by: Alex Blasche --- src/bluetooth/qbluetoothserviceinfo_osx.mm | 124 +++++++++++++++-------------- 1 file changed, 63 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/bluetooth/qbluetoothserviceinfo_osx.mm b/src/bluetooth/qbluetoothserviceinfo_osx.mm index 6da9d7a2..755e85c9 100644 --- a/src/bluetooth/qbluetoothserviceinfo_osx.mm +++ b/src/bluetooth/qbluetoothserviceinfo_osx.mm @@ -58,61 +58,41 @@ QT_BEGIN_NAMESPACE class QBluetoothServiceInfoPrivate { public: - typedef QBluetoothServiceInfo QSInfo; - QBluetoothServiceInfoPrivate(QBluetoothServiceInfo *q); - bool registerService(const QBluetoothAddress &localAdapter = QBluetoothAddress()); + typedef QBluetoothServiceInfo QSInfo; + bool registerService(const OSXBluetooth::ObjCStrongReference &serviceDict); bool isRegistered() const; - bool unregisterService(); QBluetoothDeviceInfo deviceInfo; QMap attributes; QBluetoothServiceInfo::Sequence protocolDescriptor(QBluetoothUuid::ProtocolUuid protocol) const; + QBluetoothServiceInfo::Protocol socketProtocol() const; + int protocolServiceMultiplexer() const; int serverChannel() const; private: - QBluetoothServiceInfo *q_ptr; - bool registered; + + bool registered = false; typedef OSXBluetooth::ObjCScopedPointer SDPRecord; SDPRecord serviceRecord; - BluetoothSDPServiceRecordHandle serviceRecordHandle; + BluetoothSDPServiceRecordHandle serviceRecordHandle = 0; }; -QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate(QBluetoothServiceInfo *q) - : q_ptr(q), - registered(false), - serviceRecordHandle(0) +bool QBluetoothServiceInfoPrivate::registerService(const OSXBluetooth::ObjCStrongReference &serviceDict) { - Q_ASSERT_X(q, Q_FUNC_INFO, "invalid q_ptr (null)"); -} - -bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &localAdapter) -{ - Q_UNUSED(localAdapter) - - if (registered) - return false; - - Q_ASSERT_X(!serviceRecord, Q_FUNC_INFO, "not registered, but serviceRecord is not nil"); - using namespace OSXBluetooth; - ObjCStrongReference - serviceDict(iobluetooth_service_dictionary(*q_ptr)); - - if (!serviceDict) { - qCWarning(QT_BT_OSX) << "failed to create a service dictionary"; - return false; - } + Q_ASSERT(serviceDict); + Q_ASSERT(!registered); + Q_ASSERT_X(!serviceRecord, Q_FUNC_INFO, "not registered, but serviceRecord is not nil"); SDPRecord newRecord; newRecord.reset([[IOBluetoothSDPServiceRecord publishedServiceRecordWithDictionary:serviceDict] retain]); - if (!newRecord) { qCWarning(QT_BT_OSX) << "failed to register a service record"; return false; @@ -125,21 +105,21 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &loca return false; } - const QSInfo::Protocol type = q_ptr->socketProtocol(); + const QSInfo::Protocol type = socketProtocol(); quint16 realPort = 0; QBluetoothServerPrivate *server = nullptr; bool configured = false; if (type == QBluetoothServiceInfo::L2capProtocol) { BluetoothL2CAPPSM psm = 0; - server = QBluetoothServerPrivate::registeredServer(q_ptr->protocolServiceMultiplexer(), type); + server = QBluetoothServerPrivate::registeredServer(protocolServiceMultiplexer(), type); if ([newRecord getL2CAPPSM:&psm] == kIOReturnSuccess) { configured = true; realPort = psm; } } else if (type == QBluetoothServiceInfo::RfcommProtocol) { BluetoothRFCOMMChannelID channelID = 0; - server = QBluetoothServerPrivate::registeredServer(q_ptr->serverChannel(), type); + server = QBluetoothServerPrivate::registeredServer(serverChannel(), type); if ([newRecord getRFCOMMChannelID:&channelID] == kIOReturnSuccess) { configured = true; realPort = channelID; @@ -175,17 +155,16 @@ bool QBluetoothServiceInfoPrivate::unregisterService() Q_ASSERT_X(serviceRecord, Q_FUNC_INFO, "service registered, but serviceRecord is nil"); [serviceRecord removeServiceRecord]; - serviceRecord.reset(nil); - const QSInfo::Protocol type = q_ptr->socketProtocol(); + const QSInfo::Protocol type = socketProtocol(); QBluetoothServerPrivate *server = nullptr; const QMutexLocker lock(&QBluetoothServerPrivate::channelMapMutex()); if (type == QSInfo::RfcommProtocol) - server = QBluetoothServerPrivate::registeredServer(q_ptr->serverChannel(), type); + server = QBluetoothServerPrivate::registeredServer(serverChannel(), type); else if (type == QSInfo::L2capProtocol) - server = QBluetoothServerPrivate::registeredServer(q_ptr->protocolServiceMultiplexer(), type); + server = QBluetoothServerPrivate::registeredServer(protocolServiceMultiplexer(), type); if (server) server->stopListener(); @@ -203,7 +182,19 @@ bool QBluetoothServiceInfo::isRegistered() const bool QBluetoothServiceInfo::registerService(const QBluetoothAddress &localAdapter) { - return d_ptr->registerService(localAdapter); + Q_UNUSED(localAdapter); + if (isRegistered()) + return false; + + using namespace OSXBluetooth; + + ObjCStrongReference serviceDict(iobluetooth_service_dictionary(*this)); + if (!serviceDict) { + qCWarning(QT_BT_OSX) << "failed to create a service dictionary"; + return false; + } + + return d_ptr->registerService(serviceDict); } bool QBluetoothServiceInfo::unregisterService() @@ -212,7 +203,7 @@ bool QBluetoothServiceInfo::unregisterService() } QBluetoothServiceInfo::QBluetoothServiceInfo() - : d_ptr(QSharedPointer(new QBluetoothServiceInfoPrivate(this))) + : d_ptr(new QBluetoothServiceInfoPrivate) { } @@ -272,27 +263,12 @@ void QBluetoothServiceInfo::removeAttribute(quint16 attributeId) QBluetoothServiceInfo::Protocol QBluetoothServiceInfo::socketProtocol() const { - QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm); - if (!parameters.isEmpty()) - return RfcommProtocol; - - parameters = protocolDescriptor(QBluetoothUuid::L2cap); - if (!parameters.isEmpty()) - return L2capProtocol; - - return UnknownProtocol; + return d_ptr->socketProtocol(); } int QBluetoothServiceInfo::protocolServiceMultiplexer() const { - QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::L2cap); - - if (parameters.isEmpty()) - return -1; - else if (parameters.count() == 1) - return 0; - else - return parameters.at(1).toUInt(); + return d_ptr->protocolServiceMultiplexer(); } int QBluetoothServiceInfo::serverChannel() const @@ -322,7 +298,8 @@ QList QBluetoothServiceInfo::serviceClassUuids() const QBluetoothServiceInfo &QBluetoothServiceInfo::operator=(const QBluetoothServiceInfo &other) { - d_ptr = other.d_ptr; + if (this != &other) + d_ptr = other.d_ptr; return *this; } @@ -422,16 +399,41 @@ QBluetoothServiceInfo::Sequence QBluetoothServiceInfoPrivate::protocolDescriptor return QBluetoothServiceInfo::Sequence(); } -int QBluetoothServiceInfoPrivate::serverChannel() const +QBluetoothServiceInfo::Protocol QBluetoothServiceInfoPrivate::socketProtocol() const { QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm); + if (!parameters.isEmpty()) + return QBluetoothServiceInfo::RfcommProtocol; + + parameters = protocolDescriptor(QBluetoothUuid::L2cap); + if (!parameters.isEmpty()) + return QBluetoothServiceInfo::L2capProtocol; + return QBluetoothServiceInfo::UnknownProtocol; +} + + +int QBluetoothServiceInfoPrivate::protocolServiceMultiplexer() const +{ + const QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::L2cap); if (parameters.isEmpty()) return -1; else if (parameters.count() == 1) return 0; - else - return parameters.at(1).toUInt(); + + return parameters.at(1).toUInt(); +} + + +int QBluetoothServiceInfoPrivate::serverChannel() const +{ + const QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm); + if (parameters.isEmpty()) + return -1; + else if (parameters.count() == 1) + return 0; + + return parameters.at(1).toUInt(); } QT_END_NAMESPACE -- cgit v1.2.3