Reject all callbacks with DeviceLost on wire client disconnect

When the wire is disconnected, the client will not receive any
messages from the server. We need to manually reject all callbacks.

Bug: dawn:556
Change-Id: Ia03456b3209dbe0e1e54543d344180d11d4c6f1e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/31162
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Austin Eng
2020-11-11 21:01:18 +00:00
committed by Commit Bot service account
parent 3120d5ea0d
commit b70a5b02e9
14 changed files with 180 additions and 5 deletions

View File

@@ -14,6 +14,8 @@
#include "tests/unittests/wire/WireTest.h"
#include "dawn_wire/WireClient.h"
using namespace testing;
using namespace dawn_wire;
@@ -674,3 +676,19 @@ TEST_F(WireBufferMappingTests, MaxSizeMappableBufferOOMDirectly) {
FlushClient();
}
}
// Test that registering a callback then wire disconnect calls the callback with
// DeviceLost.
TEST_F(WireBufferMappingTests, MapThenDisconnect) {
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, this);
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
}));
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize)).Times(1);
FlushClient();
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_DeviceLost, this)).Times(1);
GetWireClient()->Disconnect();
}

View File

@@ -14,6 +14,8 @@
#include "tests/unittests/wire/WireTest.h"
#include "dawn_wire/WireClient.h"
using namespace testing;
using namespace dawn_wire;
@@ -213,3 +215,64 @@ TEST_F(WireCreateReadyPipelineTest, CreateReadyRenderPipelineError) {
FlushServer();
}
// Test that registering a callback then wire disconnect calls the callback with
// DeviceLost.
TEST_F(WireCreateReadyPipelineTest, CreateReadyRenderPipelineThenDisconnect) {
WGPUShaderModuleDescriptor vertexDescriptor = {};
WGPUShaderModule vsModule = wgpuDeviceCreateShaderModule(device, &vertexDescriptor);
WGPUShaderModule apiVsModule = api.GetNewShaderModule();
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiVsModule));
WGPUProgrammableStageDescriptor fragmentStage = {};
fragmentStage.module = vsModule;
fragmentStage.entryPoint = "main";
WGPURenderPipelineDescriptor pipelineDescriptor{};
pipelineDescriptor.vertexStage.module = vsModule;
pipelineDescriptor.vertexStage.entryPoint = "main";
pipelineDescriptor.fragmentStage = &fragmentStage;
wgpuDeviceCreateReadyRenderPipeline(device, &pipelineDescriptor,
ToMockCreateReadyRenderPipelineCallback, this);
EXPECT_CALL(api, OnDeviceCreateReadyRenderPipelineCallback(apiDevice, _, _, _))
.WillOnce(InvokeWithoutArgs([&]() {
api.CallDeviceCreateReadyRenderPipelineCallback(
apiDevice, WGPUCreateReadyPipelineStatus_Success, nullptr, "");
}));
FlushClient();
EXPECT_CALL(*mockCreateReadyRenderPipelineCallback,
Call(WGPUCreateReadyPipelineStatus_DeviceLost, _, _, this))
.Times(1);
GetWireClient()->Disconnect();
}
// Test that registering a callback then wire disconnect calls the callback with
// DeviceLost.
TEST_F(WireCreateReadyPipelineTest, CreateReadyComputePipelineThenDisconnect) {
WGPUShaderModuleDescriptor csDescriptor{};
WGPUShaderModule csModule = wgpuDeviceCreateShaderModule(device, &csDescriptor);
WGPUShaderModule apiCsModule = api.GetNewShaderModule();
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiCsModule));
WGPUComputePipelineDescriptor descriptor{};
descriptor.computeStage.module = csModule;
descriptor.computeStage.entryPoint = "main";
wgpuDeviceCreateReadyComputePipeline(device, &descriptor,
ToMockCreateReadyComputePipelineCallback, this);
EXPECT_CALL(api, OnDeviceCreateReadyComputePipelineCallback(apiDevice, _, _, _))
.WillOnce(InvokeWithoutArgs([&]() {
api.CallDeviceCreateReadyComputePipelineCallback(
apiDevice, WGPUCreateReadyPipelineStatus_Success, nullptr, "");
}));
FlushClient();
EXPECT_CALL(*mockCreateReadyComputePipelineCallback,
Call(WGPUCreateReadyPipelineStatus_DeviceLost, _, _, this))
.Times(1);
GetWireClient()->Disconnect();
}

View File

@@ -14,6 +14,8 @@
#include "tests/unittests/wire/WireTest.h"
#include "dawn_wire/WireClient.h"
using namespace testing;
using namespace dawn_wire;
@@ -216,6 +218,23 @@ TEST_F(WireErrorCallbackTests, PopErrorScopeDeviceDestroyed) {
.Times(1);
}
// Test that registering a callback then wire disconnect calls the callback with
// DeviceLost.
TEST_F(WireErrorCallbackTests, PopErrorScopeThenDisconnect) {
wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
EXPECT_CALL(api, DevicePushErrorScope(apiDevice, WGPUErrorFilter_Validation)).Times(1);
EXPECT_TRUE(wgpuDevicePopErrorScope(device, ToMockDevicePopErrorScopeCallback, this));
EXPECT_CALL(api, OnDevicePopErrorScopeCallback(apiDevice, _, _)).WillOnce(Return(true));
FlushClient();
EXPECT_CALL(*mockDevicePopErrorScopeCallback,
Call(WGPUErrorType_DeviceLost, ValidStringMessage(), this))
.Times(1);
GetWireClient()->Disconnect();
}
// Test that PopErrorScope returns false if there are no error scopes.
TEST_F(WireErrorCallbackTests, PopErrorScopeEmptyStack) {
// Empty stack

View File

@@ -14,6 +14,8 @@
#include "tests/unittests/wire/WireTest.h"
#include "dawn_wire/WireClient.h"
using namespace testing;
using namespace dawn_wire;
@@ -143,6 +145,21 @@ TEST_F(WireFenceTests, OnCompletionError) {
FlushServer();
}
// Test that registering a callback then wire disconnect calls the callback with
// DeviceLost.
TEST_F(WireFenceTests, OnCompletionThenDisconnect) {
wgpuFenceOnCompletion(fence, 0, ToMockFenceOnCompletionCallback, this);
EXPECT_CALL(api, OnFenceOnCompletionCallback(apiFence, 0u, _, _))
.WillOnce(InvokeWithoutArgs([&]() {
api.CallFenceOnCompletionCallback(apiFence, WGPUFenceCompletionStatus_Success);
}));
FlushClient();
EXPECT_CALL(*mockFenceOnCompletionCallback, Call(WGPUFenceCompletionStatus_DeviceLost, this))
.Times(1);
GetWireClient()->Disconnect();
}
// Without any flushes, it is valid to wait on a value less than or equal to
// the last signaled value
TEST_F(WireFenceTests, OnCompletionSynchronousValidationSuccess) {