From 3816324555c36885f4ba8379a30a2f96066b6e6c Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 7 Oct 2020 13:15:52 +0200 Subject: helgrind 'lock order': DBTDevice: Don't abuse mtx_connect in notify[Connected|Disconnected]() callbacks or in GATTHandler lifecycle GATTHandler lifecycle has its own minimal mutex, mtx_gattHandler, no more [ab]using mtx_connect. To avoid 'lock order' issues and hence potential deadlocks: - GATTHandler construction happens now via connectGATT() into notifyConnect off-thread for LE devices. - GATTHandler disconnectGATT() happens at disconnect() upfront above the mtx_connect lock or at notifyDisconnect() the latest. - notify[Connected|Disconnected]() callbacks don't hold mtx_connect, as they only set atomic flags and notifyConnected() may issue connectGATT() off-thread (see above) Have allowDisconnect before isConnected in notify[Connected|Disconnected](), as it is queried before. Have disconnectGATT() be called last in notifyDisconnected(), as allowDisconnect and isConnected have precedent and connectGATT() queries both to avoid ctor attempt if not connected or disconnecting. getGATTService() and pingGATT() now just use getGATTHandler(), implemented merely as 'user methods', either the GATTHandler was created at notifyConnected() and hence exists or not. connectGATT(): Add noexcept as GATTHandler ctor is also noexcept; also don't throw an exception. This renders connectGATT() suitable to be excecuted off-thread. --- examples/direct_bt_scanner01/dbt_scanner01.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/direct_bt_scanner01/dbt_scanner01.cpp b/examples/direct_bt_scanner01/dbt_scanner01.cpp index 655ea4a0..db7fd78c 100644 --- a/examples/direct_bt_scanner01/dbt_scanner01.cpp +++ b/examples/direct_bt_scanner01/dbt_scanner01.cpp @@ -255,7 +255,7 @@ int main(int argc, char *argv[]) // const uint64_t t4 = getCurrentMilliseconds(); // let's check further for full GATT - std::shared_ptr gatt = device->connectGATT(); + std::shared_ptr gatt = device->getGATTHandler(); if( nullptr != gatt ) { fprintf(stderr, "GATT usedMTU %d (server) -> %d (used)\n", gatt->getServerMTU(), gatt->getUsedMTU()); -- cgit v1.2.3