[dawn][native] Call ExecutionQueue tasks without lock.
- Move out all the callbacks before calling them in order to
ensure that we don't have lock inversion issues or deadlocks
as a result of re-entrancy.
Bug: 417802523
Change-Id: I542f03f6aa0abab9ce7da95cd4f1e4e4b009b1a5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/246534
Auto-Submit: Loko Kung <lokokung@google.com>
Reviewed-by: Shrek Shao <shrekshao@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/ExecutionQueue.cpp b/src/dawn/native/ExecutionQueue.cpp
index f131ff2..3fb78aa 100644
--- a/src/dawn/native/ExecutionQueue.cpp
+++ b/src/dawn/native/ExecutionQueue.cpp
@@ -29,6 +29,7 @@
#include <atomic>
#include <utility>
+#include <vector>
namespace dawn::native {
@@ -78,12 +79,17 @@
!mCompletedSerial.compare_exchange_weak(current, uint64_t(completedSerial),
std::memory_order_acq_rel)) {
}
+
+ std::vector<Task> pending;
mWaitingTasks.Use([&](auto tasks) {
for (auto task : tasks->IterateUpTo(completedSerial)) {
- task();
+ pending.push_back(std::move(task));
}
tasks->ClearUpTo(completedSerial);
});
+ for (auto task : pending) {
+ task();
+ }
}
MaybeError ExecutionQueueBase::EnsureCommandsFlushed(ExecutionSerial serial) {
diff --git a/src/dawn/tests/end2end/BufferTests.cpp b/src/dawn/tests/end2end/BufferTests.cpp
index 379e176..a351ff2 100644
--- a/src/dawn/tests/end2end/BufferTests.cpp
+++ b/src/dawn/tests/end2end/BufferTests.cpp
@@ -62,13 +62,6 @@
GetParam().mFutureCallbackMode == wgpu::CallbackMode::WaitAnyOnly);
}
- bool IsSpontaneous() const {
- return GetParam().mFutureCallbackMode == wgpu::CallbackMode::AllowSpontaneous;
- }
- bool IsProcessEvents() const {
- return GetParam().mFutureCallbackMode == wgpu::CallbackMode::AllowProcessEvents;
- }
-
void MapAsyncAndWait(const wgpu::Buffer& buffer,
wgpu::MapMode mode,
size_t offset,
@@ -241,10 +234,6 @@
// Test that GetConstMappedRange works inside map-read callback
TEST_P(BufferMappingTests, MapRead_InCallback) {
- // TODO(crbug.com/417802523): There is a Lock inversion bug when processing events in the
- // callback.
- DAWN_TEST_UNSUPPORTED_IF(IsSpontaneous() || IsProcessEvents());
-
constexpr size_t kBufferSize = 12;
wgpu::Buffer buffer = CreateMapReadBuffer(kBufferSize);
@@ -562,10 +551,6 @@
// Test that Get(Const)MappedRange work inside map-write callback.
TEST_P(BufferMappingTests, MapWrite_InCallbackDefault) {
- // TODO(crbug.com/417802523): There is a Lock inversion bug when processing events in the
- // callback.
- DAWN_TEST_UNSUPPORTED_IF(IsSpontaneous() || IsProcessEvents());
-
wgpu::Buffer buffer = CreateMapWriteBuffer(4);
static constexpr uint32_t myData = 2934875;
@@ -588,10 +573,6 @@
// Test that Get(Const)MappedRange with range work inside map-write callback.
TEST_P(BufferMappingTests, MapWrite_InCallbackRange) {
- // TODO(crbug.com/417802523): There is a Lock inversion bug when processing events in the
- // callback.
- DAWN_TEST_UNSUPPORTED_IF(IsSpontaneous() || IsProcessEvents());
-
wgpu::Buffer buffer = CreateMapWriteBuffer(4);
static constexpr uint32_t myData = 2934875;