Title: [247381] trunk/Source/WebCore
Revision
247381
Author
you...@apple.com
Date
2019-07-11 21:22:36 -0700 (Thu, 11 Jul 2019)

Log Message

Protect CoreAudioSharedUnit::m_clients for accessing in different threads simultaneously
https://bugs.webkit.org/show_bug.cgi?id=199717

Reviewed by Eric Carlson.

Add a lock whenever accessing to m_clients.
Manual tests show that audio capture still works.

* platform/mediastream/mac/CoreAudioCaptureSource.cpp:
(WebCore::CoreAudioSharedUnit::addClient):
(WebCore::CoreAudioSharedUnit::removeClient):
(WebCore::CoreAudioSharedUnit::forEachClient const):
(WebCore::CoreAudioSharedUnit::processMicrophoneSamples):
(WebCore::CoreAudioSharedUnit::captureFailed):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (247380 => 247381)


--- trunk/Source/WebCore/ChangeLog	2019-07-12 02:35:07 UTC (rev 247380)
+++ trunk/Source/WebCore/ChangeLog	2019-07-12 04:22:36 UTC (rev 247381)
@@ -1,3 +1,20 @@
+2019-07-11  Youenn Fablet  <you...@apple.com>
+
+        Protect CoreAudioSharedUnit::m_clients for accessing in different threads simultaneously
+        https://bugs.webkit.org/show_bug.cgi?id=199717
+
+        Reviewed by Eric Carlson.
+
+        Add a lock whenever accessing to m_clients.
+        Manual tests show that audio capture still works.
+
+        * platform/mediastream/mac/CoreAudioCaptureSource.cpp:
+        (WebCore::CoreAudioSharedUnit::addClient):
+        (WebCore::CoreAudioSharedUnit::removeClient):
+        (WebCore::CoreAudioSharedUnit::forEachClient const):
+        (WebCore::CoreAudioSharedUnit::processMicrophoneSamples):
+        (WebCore::CoreAudioSharedUnit::captureFailed):
+
 2019-07-11  Chris Dumez  <cdu...@apple.com>
 
         Drop non thread-safe usage of WeakPtr in PlaybackSessionInterfaceAVKit

Modified: trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp (247380 => 247381)


--- trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp	2019-07-12 02:35:07 UTC (rev 247380)
+++ trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp	2019-07-12 04:22:36 UTC (rev 247381)
@@ -128,8 +128,11 @@
     void devicesChanged();
     void captureFailed();
 
-    Vector<std::reference_wrapper<CoreAudioCaptureSource>> m_clients;
+    void forEachClient(const Function<void(CoreAudioCaptureSource&)>& apply) const;
 
+    HashSet<CoreAudioCaptureSource*> m_clients;
+    mutable RecursiveLock m_clientsLock;
+
     AudioUnit m_ioUnit { nullptr };
 
     // Only read/modified from the IO thread.
@@ -196,16 +199,32 @@
 
 void CoreAudioSharedUnit::addClient(CoreAudioCaptureSource& client)
 {
-    m_clients.append(client);
+    auto locker = holdLock(m_clientsLock);
+    m_clients.add(&client);
 }
 
 void CoreAudioSharedUnit::removeClient(CoreAudioCaptureSource& client)
 {
-    m_clients.removeAllMatching([&](const auto& item) {
-        return &client == &item.get();
-    });
+    auto locker = holdLock(m_clientsLock);
+    m_clients.remove(&client);
 }
 
+void CoreAudioSharedUnit::forEachClient(const Function<void(CoreAudioCaptureSource&)>& apply) const
+{
+    Vector<CoreAudioCaptureSource*> clientsCopy;
+    {
+        auto locker = holdLock(m_clientsLock);
+        clientsCopy = copyToVector(m_clients);
+    }
+    for (auto* client : clientsCopy) {
+        auto locker = holdLock(m_clientsLock);
+        // Make sure the client has not been destroyed.
+        if (!m_clients.contains(client))
+            continue;
+        apply(*client);
+    }
+}
+
 void CoreAudioSharedUnit::setCaptureDevice(String&& persistentID, uint32_t captureDeviceID)
 {
     m_persistentID = WTFMove(persistentID);
@@ -509,10 +528,10 @@
     if (m_volume != 1.0)
         m_microphoneSampleBuffer->applyGain(m_volume);
 
-    for (CoreAudioCaptureSource& client : m_clients) {
+    forEachClient([&](auto& client) {
         if (client.isProducingData())
             client.audioSamplesAvailable(MediaTime(sampleTime, m_microphoneProcFormat.sampleRate()), m_microphoneSampleBuffer->bufferList(), m_microphoneProcFormat, inNumberFrames);
-    }
+    });
     return noErr;
 }
 
@@ -656,11 +675,17 @@
 void CoreAudioSharedUnit::captureFailed()
 {
     RELEASE_LOG_ERROR(WebRTC, "CoreAudioSharedUnit::captureFailed - capture failed");
-    for (CoreAudioCaptureSource& client : m_clients)
+    forEachClient([](auto& client) {
         client.captureFailed();
+    });
 
     m_producingCount = 0;
-    m_clients.clear();
+
+    {
+        auto locker = holdLock(m_clientsLock);
+        m_clients.clear();
+    }
+
     stopInternal();
     cleanupAudioUnit();
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to