Move clearing DeviceBase::mQueue from Destroy() to WillDropLastExternalRef
This member should not be cleared after Destroy() since the application may ask for it if it still has a reference to the device. Instead, only clear the member after the application has dropped their last reference to the device. Bug: chromium:1327865 Change-Id: I282482fec5db11b4c75b91ba5995d7e2599b89a1 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/91281 Reviewed-by: Loko Kung <lokokung@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
4e34192f9e
commit
2066522311
|
@ -308,6 +308,10 @@ void DeviceBase::WillDropLastExternalRef() {
|
|||
// out all remaining refs.
|
||||
Destroy();
|
||||
|
||||
// Drop te device's reference to the queue. Because the application dropped the last external
|
||||
// references, they can no longer get the queue from APIGetQueue().
|
||||
mQueue = nullptr;
|
||||
|
||||
// Reset callbacks since after this, since after dropping the last external reference, the
|
||||
// application may have freed any device-scope memory needed to run the callback.
|
||||
mUncapturedErrorCallback = [](WGPUErrorType, char const* message, void*) {
|
||||
|
@ -454,11 +458,12 @@ void DeviceBase::Destroy() {
|
|||
// implementations of DestroyImpl checks that we are disconnected before doing work.
|
||||
mState = State::Disconnected;
|
||||
|
||||
// Note: mQueue is not released here since the application may still get it after calling
|
||||
// Destroy() via APIGetQueue.
|
||||
mDynamicUploader = nullptr;
|
||||
mEmptyBindGroupLayout = nullptr;
|
||||
mInternalPipelineStore = nullptr;
|
||||
mExternalTexturePlaceholderView = nullptr;
|
||||
mQueue = nullptr;
|
||||
|
||||
AssumeCommandsComplete();
|
||||
|
||||
|
|
|
@ -190,6 +190,20 @@ TEST_P(DestroyTest, DestroyDeviceLingeringBGL) {
|
|||
DestroyDevice();
|
||||
}
|
||||
|
||||
// Regression test for crbug.com/1327865 where the device set the queue to null
|
||||
// inside Destroy() such that it could no longer return it to a call to GetQueue().
|
||||
TEST_P(DestroyTest, GetQueueAfterDeviceDestroy) {
|
||||
DestroyDevice();
|
||||
|
||||
wgpu::Queue queue = device.GetQueue();
|
||||
ASSERT_DEVICE_ERROR(queue.OnSubmittedWorkDone(
|
||||
0u,
|
||||
[](WGPUQueueWorkDoneStatus status, void* userdata) {
|
||||
EXPECT_EQ(status, WGPUQueueWorkDoneStatus_DeviceLost);
|
||||
},
|
||||
nullptr));
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(DestroyTest,
|
||||
D3D12Backend(),
|
||||
MetalBackend(),
|
||||
|
|
Loading…
Reference in New Issue