client: call pending GetCompilationInfo on Disconnect

Fixed: dawn:1090
Change-Id: Ia7cf692ea41ebe85aaac58e3f3aa6727e6cc8ba4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/63002
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Shrek Shao <shrekshao@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_wire/client/ShaderModule.cpp b/src/dawn_wire/client/ShaderModule.cpp
index 97e0204..fa7945a 100644
--- a/src/dawn_wire/client/ShaderModule.cpp
+++ b/src/dawn_wire/client/ShaderModule.cpp
@@ -63,4 +63,14 @@
         return true;
     }
 
+    void ShaderModule::CancelCallbacksForDisconnect() {
+        for (auto& it : mCompilationInfoRequests) {
+            if (it.second.callback) {
+                it.second.callback(WGPUCompilationInfoRequestStatus_DeviceLost, nullptr,
+                                   it.second.userdata);
+            }
+        }
+        mCompilationInfoRequests.clear();
+    }
+
 }}  // namespace dawn_wire::client
diff --git a/src/dawn_wire/client/ShaderModule.h b/src/dawn_wire/client/ShaderModule.h
index add5b97..d7ac55d 100644
--- a/src/dawn_wire/client/ShaderModule.h
+++ b/src/dawn_wire/client/ShaderModule.h
@@ -32,6 +32,8 @@
                                         WGPUCompilationInfoRequestStatus status,
                                         const WGPUCompilationInfo* info);
 
+        void CancelCallbacksForDisconnect() override;
+
       private:
         struct CompilationInfoRequest {
             WGPUCompilationInfoCallback callback = nullptr;
diff --git a/src/tests/unittests/wire/WireShaderModuleTests.cpp b/src/tests/unittests/wire/WireShaderModuleTests.cpp
index f4a0425..4b2db4d 100644
--- a/src/tests/unittests/wire/WireShaderModuleTests.cpp
+++ b/src/tests/unittests/wire/WireShaderModuleTests.cpp
@@ -117,4 +117,35 @@
                      _))
         .Times(1);
     FlushServer();
-}
\ No newline at end of file
+}
+
+// Test that calling GetCompilationInfo then disconnecting the wire calls the callback with a device
+// loss.
+TEST_F(WireShaderModuleTests, GetCompilationInfoBeforeDisconnect) {
+    wgpuShaderModuleGetCompilationInfo(shaderModule, ToMockGetCompilationInfoCallback, nullptr);
+
+    WGPUCompilationMessage message = {"Test Message", WGPUCompilationMessageType_Info, 2, 4, 6, 8};
+    WGPUCompilationInfo compilationInfo;
+    compilationInfo.messageCount = 1;
+    compilationInfo.messages = &message;
+
+    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _, _))
+        .WillOnce(InvokeWithoutArgs([&]() {
+            api.CallShaderModuleGetCompilationInfoCallback(
+                apiShaderModule, WGPUCompilationInfoRequestStatus_Success, &compilationInfo);
+        }));
+    FlushClient();
+
+    EXPECT_CALL(*mockCompilationInfoCallback,
+                Call(WGPUCompilationInfoRequestStatus_DeviceLost, nullptr, _));
+    GetWireClient()->Disconnect();
+}
+
+// Test that calling GetCompilationInfo after disconnecting the wire calls the callback with a
+// device loss.
+TEST_F(WireShaderModuleTests, GetCompilationInfoAfterDisconnect) {
+    GetWireClient()->Disconnect();
+    EXPECT_CALL(*mockCompilationInfoCallback,
+                Call(WGPUCompilationInfoRequestStatus_DeviceLost, nullptr, _));
+    wgpuShaderModuleGetCompilationInfo(shaderModule, ToMockGetCompilationInfoCallback, nullptr);
+}