summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@insta.fi>2022-05-13 07:48:40 +0300
committerJuha Vuolle <juha.vuolle@insta.fi>2022-05-30 09:13:23 +0300
commit3aafe9d5ce117858143dbb527f742cf875aa83e8 (patch)
treea66f2a5e4f89ec3d8eca065b7a4c5ebb7a84a4c2 /src
parent502544ad96c83b9e793e7b0e41a632477ddc002c (diff)
Close socket descriptor when QBluetoothSocketBluez is destroyed
There are two private QBluetoothSocket backends on Linux: - QBluetoothSocketBluez is native linux socket implementation It is always used by the linux QBluetoothServer, and by QBluetoothSocket if Bluez version is < 5.46 - QBluetoothSocketBluezDbus used by QBluetoothSocket when Bluez >= 5.46 Leaving the native socket unclosed leaks the resource and eventually we may run out of descriptors. This is reproducible by creating and destroying QBluetoothServer instances in a loop. As a related drive-by: - Fix bluetooth socket autotest version check. DBus socket is used with bluez 5.46+ (for clarity: DBus lowenergycontroller is used with bluez 5.42+). This is needed for the test to pass with Bluez < 5.46 - Add a clarifying comment on socket close() Fixes: QTBUG-103067 Pick-to: 5.15 6.2 6.3 Change-Id: Idc38c743be09e559ea82bf09c2f9e44e4b80d666 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth/qbluetoothsocket.cpp7
-rw-r--r--src/bluetooth/qbluetoothsocket_bluez.cpp6
2 files changed, 12 insertions, 1 deletions
diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp
index 96901c96..b65f0c56 100644
--- a/src/bluetooth/qbluetoothsocket.cpp
+++ b/src/bluetooth/qbluetoothsocket.cpp
@@ -791,10 +791,15 @@ void QBluetoothSocket::close()
Set the socket to use \a socketDescriptor with a type of \a socketType,
which is in state, \a socketState, and mode, \a openMode.
+ The set socket descriptor is considered owned by the QBluetoothSocket
+ and may be e.g. closed once finished.
+
Returns true on success
*/
-
+// ### Qt 7 consider making this function private. The qbluetoothsocket_bluez backend is the
+// the only backend providing publicly accessible support for this. Other backends implement
+// similarly named, but private, overload
bool QBluetoothSocket::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
SocketState socketState, OpenMode openMode)
{
diff --git a/src/bluetooth/qbluetoothsocket_bluez.cpp b/src/bluetooth/qbluetoothsocket_bluez.cpp
index d6987092..1739d42b 100644
--- a/src/bluetooth/qbluetoothsocket_bluez.cpp
+++ b/src/bluetooth/qbluetoothsocket_bluez.cpp
@@ -72,6 +72,10 @@ QBluetoothSocketPrivateBluez::~QBluetoothSocketPrivateBluez()
readNotifier = nullptr;
delete connectWriteNotifier;
connectWriteNotifier = nullptr;
+
+ // If the socket wasn't closed/aborted make sure we free the socket file descriptor
+ if (socket != -1)
+ QT_CLOSE(socket);
}
bool QBluetoothSocketPrivateBluez::ensureNativeSocket(QBluetoothServiceInfo::Protocol type)
@@ -618,6 +622,8 @@ qint64 QBluetoothSocketPrivateBluez::readData(char *data, qint64 maxSize)
void QBluetoothSocketPrivateBluez::close()
{
+ // If we have pending data on the write buffer, wait until it has been written,
+ // after which this close() will be called again
if (txBuffer.size() > 0)
connectWriteNotifier->setEnabled(true);
else