[dawn][native] Use the new Defer options for MapAsync callbacks.

- By using the new Defer option for the MapAsync callbacks, we can
  simplify the code a bit and avoid returning the Event everywhere.

Bug: 412761228
Change-Id: Ic70dcac78a326e9a50d670c585bbf16d35f91218
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/249098
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 73fdb72..1ad4a9c 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -647,8 +647,7 @@
                 "returns": "buffer map state"
             },
             {
-                "name": "unmap",
-                "no autolock": true
+                "name": "unmap"
             },
             {
                 "name": "destroy"
diff --git a/src/dawn/native/Buffer.cpp b/src/dawn/native/Buffer.cpp
index adffb03..9b85cb9 100644
--- a/src/dawn/native/Buffer.cpp
+++ b/src/dawn/native/Buffer.cpp
@@ -381,15 +381,13 @@
 }
 
 void BufferBase::DestroyImpl() {
-    Ref<MapAsyncEvent> event;
-
     switch (mState.load(std::memory_order::acquire)) {
         case BufferState::Mapped:
         case BufferState::PendingMap: {
             [[maybe_unused]] bool hadError = GetDevice()->ConsumedError(
                 UnmapInternal(WGPUMapAsyncStatus_Aborted,
                               "Buffer was destroyed before mapping was resolved."),
-                &event, "calling %s.Destroy().", this);
+                "calling %s.Destroy().", this);
             break;
         }
         case BufferState::MappedAtCreation: {
@@ -399,7 +397,7 @@
                 [[maybe_unused]] bool hadError = GetDevice()->ConsumedError(
                     UnmapInternal(WGPUMapAsyncStatus_Aborted,
                                   "Buffer was destroyed before mapping was resolved."),
-                    &event, "calling %s.Destroy().", this);
+                    "calling %s.Destroy().", this);
             }
             break;
         }
@@ -407,16 +405,6 @@
             break;
     }
     mState.store(BufferState::Destroyed, std::memory_order::release);
-
-    // This is the error cases where re-entrant API calls, specifically Unmap will fail since
-    // this function is called in two places, via Buffer::APIDestroy and Device::Destroy, both which
-    // currently hold the device-wide lock which we don't yet have a way to circumvent and release
-    // before the callback is called (spontaneously). That said, this only happens if a user is
-    // calling Unmap in the MapAsync callback even though the callback was Aborted which is an
-    // invalid use case.
-    if (event) {
-        GetInstance()->GetEventManager()->SetFutureReady(event.Get());
-    }
 }
 
 // static
@@ -692,21 +680,13 @@
 }
 
 void BufferBase::APIUnmap() {
-    Ref<MapAsyncEvent> event;
-    {
-        auto deviceGuard = GetDevice()->GetGuard();
-        if (GetDevice()->ConsumedError(ValidateUnmap(), "calling %s.Unmap().", this)) {
-            return;
-        }
-        [[maybe_unused]] bool hadError = GetDevice()->ConsumedError(
-            UnmapInternal(WGPUMapAsyncStatus_Aborted,
-                          "Buffer was unmapped before mapping was resolved."),
-            &event, "calling %s.Unmap().", this);
+    if (GetDevice()->ConsumedError(ValidateUnmap(), "calling %s.Unmap().", this)) {
+        return;
     }
-
-    if (event) {
-        GetInstance()->GetEventManager()->SetFutureReady(event.Get());
-    }
+    [[maybe_unused]] bool hadError = GetDevice()->ConsumedError(
+        UnmapInternal(WGPUMapAsyncStatus_Aborted,
+                      "Buffer was unmapped before mapping was resolved."),
+        "calling %s.Unmap().", this);
 }
 
 MaybeError BufferBase::Unmap() {
@@ -736,31 +716,33 @@
     return {};
 }
 
-ResultOrError<Ref<BufferBase::MapAsyncEvent>> BufferBase::UnmapInternal(WGPUMapAsyncStatus status,
-                                                                        std::string_view message) {
-    Ref<MapAsyncEvent> event;
-
+MaybeError BufferBase::UnmapInternal(WGPUMapAsyncStatus status, std::string_view message) {
     BufferState state = mState.load(std::memory_order::acquire);
 
     // If the buffer is already destroyed, we don't need to do anything.
     if (state == BufferState::Destroyed) {
-        return nullptr;
+        return {};
     }
 
-    // For pending maps, set the pending event statuses, and return it. The caller is responsible
-    // for setting the event to be ready once we no longer are holding the device-wide lock.
     if (state == BufferState::PendingMap) {
         // For pending maps, we update the pending event, and only set it to ready after releasing
         // the buffer state lock so that spontaneous callbacks with re-entrant calls work properly.
-        event = std::get<Ref<MapAsyncEvent>>(std::exchange(mMapData, static_cast<void*>(nullptr)));
+        Ref<MapAsyncEvent> event =
+            std::get<Ref<MapAsyncEvent>>(std::exchange(mMapData, static_cast<void*>(nullptr)));
+
         event->UnmapEarly(status, message);
         UnmapImpl();
         mState.store(BufferState::Unmapped, std::memory_order::release);
-        return std::move(event);
+
+        GetDevice()->DeferIfLocked(
+            [eventManager = GetInstance()->GetEventManager(), mapEvent = std::move(event)]() {
+                eventManager->SetFutureReady(mapEvent.Get());
+            });
+        return {};
     }
 
     DAWN_TRY(Unmap());
-    return nullptr;
+    return {};
 }
 
 MaybeError BufferBase::ValidateMapAsync(wgpu::MapMode mode,
diff --git a/src/dawn/native/Buffer.h b/src/dawn/native/Buffer.h
index 41148d0..ac09b4f 100644
--- a/src/dawn/native/Buffer.h
+++ b/src/dawn/native/Buffer.h
@@ -175,11 +175,7 @@
                                 WGPUMapAsyncStatus* status) const;
     MaybeError ValidateUnmap() const;
     bool CanGetMappedRange(bool writable, size_t offset, size_t size) const;
-
-    // Unmaps the buffer and returns a MapAsyncEvent that should be set to ready if the buffer had a
-    // pending map event.
-    ResultOrError<Ref<MapAsyncEvent>> UnmapInternal(WGPUMapAsyncStatus status,
-                                                    std::string_view message);
+    MaybeError UnmapInternal(WGPUMapAsyncStatus status, std::string_view message);
 
     // Updates internal state to reflect that the buffer is now mapped.
     void SetMapped(BufferState newState);