From ed8328d8cdcae25ef85c72a233fe9e2f45fed333 Mon Sep 17 00:00:00 2001 From: Victor Gaydov Date: Sat, 4 May 2024 13:40:12 +0400 Subject: [PATCH] Add protection from adding/removing device twice If Plugin::AddDevice() or RemoveDevice() is called twice for same device, the second call is now ignored. --- src/Plugin.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/Plugin.cpp b/src/Plugin.cpp index f9915c7..8fd8b5f 100644 --- a/src/Plugin.cpp +++ b/src/Plugin.cpp @@ -88,6 +88,27 @@ void Plugin::AddDevice(std::shared_ptr device) GetContext()->Tracer->OperationBegin(op); + if (auto devOwner = device->GetOwnerID(); devOwner != kAudioObjectUnknown) { + if (devOwner == GetID()) { + // Protection from adding same device twice. + GetContext()->Tracer->Message( + "Plugin::AddDevice() device already added" + " devID=%lu pluginID=%lu", + static_cast(device->GetID()), + static_cast(GetID())); + } else { + // This is likely a bug in user code. Only Plugin can be + // Device owner, and there is only one plugin. + GetContext()->Tracer->Message( + "Plugin::AddDevice() unexpected device owner" + " devID=%lu devOwnerID=%lu pluginID=%lu", + static_cast(device->GetID()), + static_cast(device->GetOwnerID()), + static_cast(GetID())); + } + goto end; + } + { auto devices = devices_.Get(); @@ -117,6 +138,7 @@ void Plugin::AddDevice(std::shared_ptr device) NotifyPropertiesChanged( {kAudioObjectPropertyOwnedObjects, kAudioPlugInPropertyDeviceList}); +end: GetContext()->Tracer->OperationEnd(op, kAudioHardwareNoError); } @@ -130,6 +152,16 @@ void Plugin::RemoveDevice(std::shared_ptr device) GetContext()->Tracer->OperationBegin(op); + if (device->GetOwnerID() == kAudioObjectUnknown) { + // Protection from removing same device twice. + GetContext()->Tracer->Message( + "Plugin::RemoveDevice() device already removed" + " devID=%lu pluginID=%lu", + static_cast(device->GetID()), + static_cast(GetID())); + goto end; + } + { auto devices = devices_.Get(); @@ -163,6 +195,7 @@ void Plugin::RemoveDevice(std::shared_ptr device) NotifyPropertiesChanged( {kAudioObjectPropertyOwnedObjects, kAudioPlugInPropertyDeviceList}); +end: GetContext()->Tracer->OperationEnd(op, kAudioHardwareNoError); }