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;