Title: [276263] trunk/Source/WebKit
Revision
276263
Author
[email protected]
Date
2021-04-19 10:53:04 -0700 (Mon, 19 Apr 2021)

Log Message

Fix races in LibWebRTCCodecs introduced in r276214
https://bugs.webkit.org/show_bug.cgi?id=224758

Reviewed by Youenn Fablet.

After r276214, LibWebRTCCodecs's createDecoder() / createEncoder() may hop to the main
thread to initialize the connection to the GPUProcess. If releaseDecoder() / releaseEncoder()
were to get called very shortly after, they may win the race and have no decoder / encoder
to release, since they are dispatched directly to the background thread. To address the issue,
we now call ensureGPUProcessConnectionAndDispatchToThread() in releaseDecoder(), releaseEncoder()
and initializeEncoder().

* WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
(WebKit::LibWebRTCCodecs::releaseDecoder):
(WebKit::LibWebRTCCodecs::releaseEncoder):
(WebKit::LibWebRTCCodecs::initializeEncoder):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (276262 => 276263)


--- trunk/Source/WebKit/ChangeLog	2021-04-19 17:51:46 UTC (rev 276262)
+++ trunk/Source/WebKit/ChangeLog	2021-04-19 17:53:04 UTC (rev 276263)
@@ -1,5 +1,24 @@
 2021-04-19  Chris Dumez  <[email protected]>
 
+        Fix races in LibWebRTCCodecs introduced in r276214
+        https://bugs.webkit.org/show_bug.cgi?id=224758
+
+        Reviewed by Youenn Fablet.
+
+        After r276214, LibWebRTCCodecs's createDecoder() / createEncoder() may hop to the main
+        thread to initialize the connection to the GPUProcess. If releaseDecoder() / releaseEncoder()
+        were to get called very shortly after, they may win the race and have no decoder / encoder
+        to release, since they are dispatched directly to the background thread. To address the issue,
+        we now call ensureGPUProcessConnectionAndDispatchToThread() in releaseDecoder(), releaseEncoder()
+        and initializeEncoder().
+
+        * WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
+        (WebKit::LibWebRTCCodecs::releaseDecoder):
+        (WebKit::LibWebRTCCodecs::releaseEncoder):
+        (WebKit::LibWebRTCCodecs::initializeEncoder):
+
+2021-04-19  Chris Dumez  <[email protected]>
+
         Add more GPUProcess release logging to facilitate debugging
         https://bugs.webkit.org/show_bug.cgi?id=224761
 

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp (276262 => 276263)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp	2021-04-19 17:51:46 UTC (rev 276262)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp	2021-04-19 17:53:04 UTC (rev 276263)
@@ -191,15 +191,25 @@
 void LibWebRTCCodecs::ensureGPUProcessConnectionAndDispatchToThread(Function<void()>&& task)
 {
     m_needsGPUProcessConnection = true;
-    {
-        auto locker = holdLock(m_connectionLock);
-        if (m_connection)
-            return dispatchToThread(WTFMove(task));
+
+    auto locker = holdLock(m_connectionLock);
+
+    // Fast path when we already have a connection.
+    if (m_connection) {
+        dispatchToThread(WTFMove(task));
+        return;
     }
-    ensureOnMainRunLoop([this, task = WTFMove(task)]() mutable {
+
+    // We don't have a connection to the GPUProcess yet, we need to hop to the main thread to initiate it.
+    m_tasksToDispatchAfterEstablishingConnection.append(WTFMove(task));
+    if (m_tasksToDispatchAfterEstablishingConnection.size() != 1)
+        return;
+
+    callOnMainRunLoop([this] {
         auto locker = holdLock(m_connectionLock);
         ensureGPUProcessConnectionOnMainThread(locker);
-        dispatchToThread(WTFMove(task));
+        for (auto& task : std::exchange(m_tasksToDispatchAfterEstablishingConnection, { }))
+            dispatchToThread(WTFMove(task));
     });
 }
 
@@ -259,7 +269,7 @@
 int32_t LibWebRTCCodecs::releaseDecoder(Decoder& decoder)
 {
     ASSERT(!decoder.decodedImageCallback);
-    dispatchToThread([this, decoderIdentifier = decoder.identifier] {
+    ensureGPUProcessConnectionAndDispatchToThread([this, decoderIdentifier = decoder.identifier] {
         ASSERT(m_decoders.contains(decoderIdentifier));
         if (auto decoder = m_decoders.take(decoderIdentifier)) {
             decoder->connection->send(Messages::LibWebRTCCodecsProxy::ReleaseDecoder { decoderIdentifier }, 0);
@@ -382,7 +392,7 @@
 int32_t LibWebRTCCodecs::releaseEncoder(Encoder& encoder)
 {
     ASSERT(!encoder.encodedImageCallback);
-    dispatchToThread([this, encoderIdentifier = encoder.identifier] {
+    ensureGPUProcessConnectionAndDispatchToThread([this, encoderIdentifier = encoder.identifier] {
         ASSERT(m_encoders.contains(encoderIdentifier));
         auto encoder = m_encoders.take(encoderIdentifier);
         encoder->connection->send(Messages::LibWebRTCCodecsProxy::ReleaseEncoder { encoderIdentifier }, 0);
@@ -393,7 +403,7 @@
 
 int32_t LibWebRTCCodecs::initializeEncoder(Encoder& encoder, uint16_t width, uint16_t height, unsigned startBitRate, unsigned maxBitRate, unsigned minBitRate, uint32_t maxFrameRate)
 {
-    dispatchToThread([this, encoderIdentifier = encoder.identifier, width, height, startBitRate, maxBitRate, minBitRate, maxFrameRate]() mutable {
+    ensureGPUProcessConnectionAndDispatchToThread([this, encoderIdentifier = encoder.identifier, width, height, startBitRate, maxBitRate, minBitRate, maxFrameRate]() mutable {
         auto* encoder = m_encoders.get(encoderIdentifier);
         encoder->initializationData = EncoderInitializationData { width, height, startBitRate, maxBitRate, minBitRate, maxFrameRate };
         encoder->connection->send(Messages::LibWebRTCCodecsProxy::InitializeEncoder { encoderIdentifier, width, height, startBitRate, maxBitRate, minBitRate, maxFrameRate }, 0);

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h (276262 => 276263)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h	2021-04-19 17:51:46 UTC (rev 276262)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h	2021-04-19 17:53:04 UTC (rev 276263)
@@ -145,6 +145,8 @@
 
     Lock m_connectionLock;
     RefPtr<IPC::Connection> m_connection;
+    Vector<Function<void()>> m_tasksToDispatchAfterEstablishingConnection;
+
     Ref<WorkQueue> m_queue;
     std::unique_ptr<WebCore::ImageTransferSessionVT> m_imageTransferSession;
     std::unique_ptr<WebCore::PixelBufferConformerCV> m_pixelBufferConformer;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to