diff --git a/internal/platform/implementation/linux/bluetooth_bluez_profile.cc b/internal/platform/implementation/linux/bluetooth_bluez_profile.cc index 2f51f187..ac66837e 100644 --- a/internal/platform/implementation/linux/bluetooth_bluez_profile.cc +++ b/internal/platform/implementation/linux/bluetooth_bluez_profile.cc @@ -27,6 +27,7 @@ #include #include "absl/synchronization/mutex.h" +#include "internal/platform/cancellation_flag_listener.h" #include "internal/platform/implementation/linux/bluetooth_bluez_profile.h" #include "internal/platform/implementation/linux/bluetooth_classic_device.h" #include "internal/platform/implementation/linux/bluetooth_devices.h" @@ -191,6 +192,14 @@ std::optional ProfileManager::GetServiceRecordFD( auto profile = registered_services_[std::string(service_uuid)]; registered_service_uuids_mutex_.ReaderUnlock(); + std::unique_ptr cancel_listener; + if (cancellation_flag != nullptr) + cancel_listener = std::make_unique( + cancellation_flag, [&profile]() { + profile->connections_lock_.Lock(); + profile->connections_lock_.Unlock(); + }); + NEARBY_LOGS(VERBOSE) << __func__ << ": " << profile->getObjectPath() << ": Attempting to get a FD for service " << service_uuid << " on device " << mac_addr; @@ -225,7 +234,7 @@ std::optional ProfileManager::GetServiceRecordFD( // with its FD. std::optional, sdbus::UnixFd>> ProfileManager::GetServiceRecordFD(absl::string_view service_uuid, - const CancellationFlag &cancellation_flag) { + CancellationFlag *cancellation_flag) { if (!ProfileRegistered(service_uuid)) { return std::nullopt; } @@ -238,14 +247,23 @@ ProfileManager::GetServiceRecordFD(absl::string_view service_uuid, << ": Attempting to get a FD for service " << service_uuid; + std::unique_ptr cancel_listener; + if (cancellation_flag != nullptr) + cancel_listener = std::make_unique( + cancellation_flag, [&profile]() { + profile->connections_lock_.Lock(); + profile->connections_lock_.Unlock(); + }); + profile->connections_lock_.Lock(); auto cond = [profile, &cancellation_flag]() { profile->connections_lock_.AssertReaderHeld(); - return !profile->connections_.empty() || cancellation_flag.Cancelled(); + return !profile->connections_.empty() || + (cancellation_flag != nullptr && cancellation_flag->Cancelled()); }; profile->connections_lock_.Await(absl::Condition(&cond)); - if (cancellation_flag.Cancelled()) { + if (cancellation_flag != nullptr && cancellation_flag->Cancelled()) { NEARBY_LOGS(VERBOSE) << __func__ << "Cancelled waiting for new connections on profile " << profile->getObjectPath(); diff --git a/internal/platform/implementation/linux/bluetooth_bluez_profile.h b/internal/platform/implementation/linux/bluetooth_bluez_profile.h index c9cda470..c92ab821 100644 --- a/internal/platform/implementation/linux/bluetooth_bluez_profile.h +++ b/internal/platform/implementation/linux/bluetooth_bluez_profile.h @@ -131,7 +131,7 @@ class ProfileManager final std::optional< std::pair, sdbus::UnixFd>> GetServiceRecordFD(absl::string_view service_uuid, - const CancellationFlag &cancellation_flag) + CancellationFlag *cancellation_flag) ABSL_LOCKS_EXCLUDED(registered_service_uuids_mutex_); private: diff --git a/internal/platform/implementation/linux/bluetooth_classic_server_socket.cc b/internal/platform/implementation/linux/bluetooth_classic_server_socket.cc index d06741ca..489423cc 100644 --- a/internal/platform/implementation/linux/bluetooth_classic_server_socket.cc +++ b/internal/platform/implementation/linux/bluetooth_classic_server_socket.cc @@ -31,7 +31,7 @@ std::unique_ptr BluetoothServerSocket::Accept() { << ": accepting new connections for service uuid " << service_uuid_; - auto pair = profile_manager_.GetServiceRecordFD(service_uuid_, stopped_); + auto pair = profile_manager_.GetServiceRecordFD(service_uuid_, &stopped_); if (!pair.has_value()) { NEARBY_LOGS(ERROR) << __func__ << "Failed to get a new connection for profile "