Title: [276284] trunk
Revision
276284
Author
[email protected]
Date
2021-04-19 21:49:46 -0700 (Mon, 19 Apr 2021)

Log Message

REGRESSION (r276189): GPUProcess.WebProcessTerminationAfterTooManyGPUProcessCrashes is crashing
https://bugs.webkit.org/show_bug.cgi?id=224790
<rdar://problem/76869318>

Reviewed by Darin Adler.

Source/WebKit:

GPUProcess.WebProcessTerminationAfterTooManyGPUProcessCrashes is intentionally repeatedly
killing the GPUProcess. As a result, the GPUProcess may get killed very shortly after
a relaunch and the RemoteAudioDestinationManager::StartAudioDestination synchronous IPC
may fail if it is ongoing at the time of the crash. This would cause m_destinationID to
not get initialized and then get sent as IPC parameter, thus crashing.

pre-r276189, we were not crashing because m_destinationID was not reset on crash and we
would thus send IPC for a destination that does not exist but at least the destinationID
would not be 0. This patch makes sure we don't try and send IPC at all when m_destinationID
is 0.

* WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp:
(WebKit::RemoteAudioDestinationProxy::connection):
(WebKit::RemoteAudioDestinationProxy::startRendering):
(WebKit::RemoteAudioDestinationProxy::stopRendering):
(WebKit::RemoteAudioDestinationProxy::storageChanged):
* WebProcess/GPU/media/RemoteAudioDestinationProxy.h:

Tools:

Re-enable API test now that it is no longer crashing.

* TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm:
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (276283 => 276284)


--- trunk/Source/WebKit/ChangeLog	2021-04-20 04:45:42 UTC (rev 276283)
+++ trunk/Source/WebKit/ChangeLog	2021-04-20 04:49:46 UTC (rev 276284)
@@ -1,3 +1,29 @@
+2021-04-19  Chris Dumez  <[email protected]>
+
+        REGRESSION (r276189): GPUProcess.WebProcessTerminationAfterTooManyGPUProcessCrashes is crashing
+        https://bugs.webkit.org/show_bug.cgi?id=224790
+        <rdar://problem/76869318>
+
+        Reviewed by Darin Adler.
+
+        GPUProcess.WebProcessTerminationAfterTooManyGPUProcessCrashes is intentionally repeatedly
+        killing the GPUProcess. As a result, the GPUProcess may get killed very shortly after
+        a relaunch and the RemoteAudioDestinationManager::StartAudioDestination synchronous IPC
+        may fail if it is ongoing at the time of the crash. This would cause m_destinationID to
+        not get initialized and then get sent as IPC parameter, thus crashing.
+
+        pre-r276189, we were not crashing because m_destinationID was not reset on crash and we
+        would thus send IPC for a destination that does not exist but at least the destinationID
+        would not be 0. This patch makes sure we don't try and send IPC at all when m_destinationID
+        is 0.
+
+        * WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp:
+        (WebKit::RemoteAudioDestinationProxy::connection):
+        (WebKit::RemoteAudioDestinationProxy::startRendering):
+        (WebKit::RemoteAudioDestinationProxy::stopRendering):
+        (WebKit::RemoteAudioDestinationProxy::storageChanged):
+        * WebProcess/GPU/media/RemoteAudioDestinationProxy.h:
+
 2021-04-19  Jer Noble  <[email protected]>
 
         [iOS] Media playback continues after backgrounding hosting application

Modified: trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp (276283 => 276284)


--- trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp	2021-04-20 04:45:42 UTC (rev 276283)
+++ trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp	2021-04-20 04:49:46 UTC (rev 276284)
@@ -98,12 +98,18 @@
     m_renderThread = nullptr;
 }
 
-GPUProcessConnection& RemoteAudioDestinationProxy::ensureGPUProcessConnection()
+IPC::Connection* RemoteAudioDestinationProxy::connection()
 {
     if (!m_gpuProcessConnection) {
         m_gpuProcessConnection = makeWeakPtr(WebProcess::singleton().ensureGPUProcessConnection());
         m_gpuProcessConnection->addClient(*this);
 
+        if (!m_gpuProcessConnection->connection().sendSync(Messages::RemoteAudioDestinationManager::CreateAudioDestination(m_inputDeviceId, m_numberOfInputChannels, numberOfOutputChannels(), sampleRate(), hardwareSampleRate(), m_renderSemaphore), Messages::RemoteAudioDestinationManager::CreateAudioDestination::Reply(m_destinationID), 0)) {
+            // The GPUProcess likely crashed during this synchronous IPC. gpuProcessConnectionDidClose() will get called to reconnect to the GPUProcess.
+            RELEASE_LOG_ERROR(Media, "RemoteAudioDestinationProxy::destinationID: IPC to create the audio destination failed, the GPUProcess likely crashed.");
+            return nullptr;
+        }
+
 #if PLATFORM(COCOA)
         m_currentFrame = 0;
         AudioStreamBasicDescription streamFormat;
@@ -115,14 +121,12 @@
 
         startRenderingThread();
     }
-    return *m_gpuProcessConnection;
+    return m_destinationID ? &m_gpuProcessConnection->connection() : nullptr;
 }
 
-RemoteAudioDestinationIdentifier RemoteAudioDestinationProxy::destinationID()
+IPC::Connection* RemoteAudioDestinationProxy::existingConnection()
 {
-    if (!m_destinationID)
-        ensureGPUProcessConnection().connection().sendSync(Messages::RemoteAudioDestinationManager::CreateAudioDestination(m_inputDeviceId, m_numberOfInputChannels, numberOfOutputChannels(), sampleRate(), hardwareSampleRate(), m_renderSemaphore), Messages::RemoteAudioDestinationManager::CreateAudioDestination::Reply(m_destinationID), 0);
-    return m_destinationID;
+    return m_gpuProcessConnection && m_destinationID ? &m_gpuProcessConnection->connection() : nullptr;
 }
 
 RemoteAudioDestinationProxy::~RemoteAudioDestinationProxy()
@@ -139,7 +143,11 @@
 
 void RemoteAudioDestinationProxy::startRendering(CompletionHandler<void(bool)>&& completionHandler)
 {
-    ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StartAudioDestination(destinationID()), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable {
+    auto* connection = this->connection();
+    if (!connection)
+        return completionHandler(false);
+
+    connection->sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StartAudioDestination(m_destinationID), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable {
         setIsPlaying(isPlaying);
         completionHandler(isPlaying);
     });
@@ -147,7 +155,11 @@
 
 void RemoteAudioDestinationProxy::stopRendering(CompletionHandler<void(bool)>&& completionHandler)
 {
-    ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StopAudioDestination(destinationID()), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable {
+    auto* connection = this->connection();
+    if (!connection)
+        return completionHandler(false);
+
+    connection->sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StopAudioDestination(m_destinationID), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable {
         setIsPlaying(isPlaying);
         completionHandler(!isPlaying);
     });
@@ -167,7 +179,8 @@
 #if PLATFORM(COCOA)
 void RemoteAudioDestinationProxy::storageChanged(SharedMemory* storage, const WebCore::CAAudioStreamDescription& format, size_t frameCount)
 {
-    if (!m_gpuProcessConnection)
+    auto* connection = existingConnection();
+    if (!connection)
         return;
 
     SharedMemory::Handle handle;
@@ -181,7 +194,7 @@
     uint64_t dataSize = 0;
 #endif
 
-    m_gpuProcessConnection->connection().send(Messages::RemoteAudioDestinationManager::AudioSamplesStorageChanged { destinationID(), SharedMemory::IPCHandle { WTFMove(handle), dataSize }, format, frameCount }, 0);
+    m_gpuProcessConnection->connection().send(Messages::RemoteAudioDestinationManager::AudioSamplesStorageChanged { m_destinationID, SharedMemory::IPCHandle { WTFMove(handle), dataSize }, format, frameCount }, 0);
 }
 #endif
 

Modified: trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.h (276283 => 276284)


--- trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.h	2021-04-20 04:45:42 UTC (rev 276283)
+++ trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.h	2021-04-20 04:49:46 UTC (rev 276284)
@@ -79,8 +79,8 @@
     void stopRenderingThread();
     void renderQuantum();
 
-    RemoteAudioDestinationIdentifier destinationID();
-    GPUProcessConnection& ensureGPUProcessConnection();
+    IPC::Connection* connection();
+    IPC::Connection* existingConnection();
 
     // GPUProcessConnection::Client.
     void gpuProcessConnectionDidClose(GPUProcessConnection&) final;

Modified: trunk/Tools/ChangeLog (276283 => 276284)


--- trunk/Tools/ChangeLog	2021-04-20 04:45:42 UTC (rev 276283)
+++ trunk/Tools/ChangeLog	2021-04-20 04:49:46 UTC (rev 276284)
@@ -1,5 +1,18 @@
 2021-04-19  Chris Dumez  <[email protected]>
 
+        REGRESSION (r276189): GPUProcess.WebProcessTerminationAfterTooManyGPUProcessCrashes is crashing
+        https://bugs.webkit.org/show_bug.cgi?id=224790
+        <rdar://problem/76869318>
+
+        Reviewed by Darin Adler.
+
+        Re-enable API test now that it is no longer crashing.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm:
+        (TEST):
+
+2021-04-19  Chris Dumez  <[email protected]>
+
         Unreviewed, temporarily disable GPUProcess.DISABLED_WebProcessTerminationAfterTooManyGPUProcessCrashes
         https://bugs.webkit.org/show_bug.cgi?id=224790
 

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm (276283 => 276284)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm	2021-04-20 04:45:42 UTC (rev 276283)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm	2021-04-20 04:49:46 UTC (rev 276284)
@@ -115,7 +115,7 @@
     EXPECT_TRUE([webView _isPlayingAudio]);
 }
 
-TEST(GPUProcess, DISABLED_WebProcessTerminationAfterTooManyGPUProcessCrashes)
+TEST(GPUProcess, WebProcessTerminationAfterTooManyGPUProcessCrashes)
 {
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForMediaEnabled"));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to