mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-16 16:37:08 +00:00
dawn_wire: Skip device inject error if the client drops the device
If the client drops the last reference to the device, it would dereference an invalid pointer upon calling InjectError. So, skip the call. We can't keep the device alive if the Buffer is still alive because we intend to make all objects internally null if you delete their device. It is ok to skip error injection because if the client deletes the device, it should not expect to receive any more error callbacks. Bug: dawn:384 Change-Id: I4c694310e4395b06cd49603fc5d4cd846799decb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/37580 Reviewed-by: Jiawei Shao <jiawei.shao@intel.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
3639186e7e
commit
8c58491d25
@@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "tests/MockCallback.h"
|
||||
#include "tests/unittests/wire/WireTest.h"
|
||||
|
||||
using namespace testing;
|
||||
@@ -43,3 +44,46 @@ TEST_F(WireDestroyObjectTests, DestroyDeviceDestroysChildren) {
|
||||
wgpuCommandEncoderFinish(encoder, nullptr);
|
||||
FlushClient(false);
|
||||
}
|
||||
|
||||
// Test that calling a function that would generate an InjectError doesn't crash after
|
||||
// the device is destroyed.
|
||||
TEST_F(WireDestroyObjectTests, ImplicitInjectErrorAfterDestroyDevice) {
|
||||
WGPUBufferDescriptor bufferDesc = {};
|
||||
bufferDesc.size = 4;
|
||||
WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &bufferDesc);
|
||||
|
||||
WGPUBuffer apiBuffer = api.GetNewBuffer();
|
||||
EXPECT_CALL(api, DeviceCreateBuffer(apiDevice, _)).WillOnce(Return(apiBuffer));
|
||||
|
||||
FlushClient();
|
||||
|
||||
{
|
||||
// Control case: MapAsync errors on invalid WGPUMapMode.
|
||||
MockCallback<WGPUBufferMapCallback> mockBufferMapCallback;
|
||||
|
||||
EXPECT_CALL(api, DeviceInjectError(apiDevice, WGPUErrorType_Validation, _));
|
||||
EXPECT_CALL(mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, this));
|
||||
wgpuBufferMapAsync(buffer, WGPUMapMode(0), 0, 4, mockBufferMapCallback.Callback(),
|
||||
mockBufferMapCallback.MakeUserdata(this));
|
||||
|
||||
FlushClient();
|
||||
}
|
||||
|
||||
{
|
||||
// Now, release the device. InjectError shouldn't happen.
|
||||
wgpuDeviceRelease(device);
|
||||
MockCallback<WGPUBufferMapCallback> mockBufferMapCallback;
|
||||
|
||||
EXPECT_CALL(mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, this + 1));
|
||||
wgpuBufferMapAsync(buffer, WGPUMapMode(0), 0, 4, mockBufferMapCallback.Callback(),
|
||||
mockBufferMapCallback.MakeUserdata(this + 1));
|
||||
|
||||
Sequence s1, s2;
|
||||
// The device and child objects alre also released.
|
||||
EXPECT_CALL(api, BufferRelease(apiBuffer)).InSequence(s1);
|
||||
EXPECT_CALL(api, QueueRelease(apiQueue)).InSequence(s2);
|
||||
EXPECT_CALL(api, DeviceRelease(apiDevice)).InSequence(s1, s2);
|
||||
|
||||
FlushClient();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user