[emscripten] Fix unmapping of mappedAtCreation buffers

Fixed: 415523543
Change-Id: If5f877d84e5d9611e10e1e1737fbcc020e985543
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/255735
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/emdawnwebgpu/tests/FuturesTests.cpp b/src/emdawnwebgpu/tests/FuturesTests.cpp
index 8fb29fa..76dced1 100644
--- a/src/emdawnwebgpu/tests/FuturesTests.cpp
+++ b/src/emdawnwebgpu/tests/FuturesTests.cpp
@@ -315,6 +315,26 @@
     dst.Unmap();
 }
 
+TEST_F(DeviceLevelTests, BufferMappedAtCreationUnmapRemap) {
+    static constexpr size_t kSize = 4;
+    wgpu::BufferDescriptor desc{
+        .usage = wgpu::BufferUsage::MapWrite, .size = kSize, .mappedAtCreation = true};
+    wgpu::Buffer buffer = device.CreateBuffer(&desc);
+    EXPECT_EQ(buffer.GetMapState(), wgpu::BufferMapState::Mapped);
+
+    buffer.Unmap();
+    EXPECT_EQ(buffer.GetMapState(), wgpu::BufferMapState::Unmapped);
+
+    EXPECT_EQ(instance.WaitAny(
+                  buffer.MapAsync(wgpu::MapMode::Write, 0, kSize, wgpu::CallbackMode::WaitAnyOnly,
+                                  [&buffer](wgpu::MapAsyncStatus s, wgpu::StringView) {
+                                      ASSERT_EQ(s, wgpu::MapAsyncStatus::Success);
+                                      EXPECT_EQ(buffer.GetMapState(), wgpu::BufferMapState::Mapped);
+                                  }),
+                  UINT64_MAX),
+              wgpu::WaitStatus::Success);
+}
+
 TEST_F(DeviceLevelTests, CreateComputePipelineAsync) {
     wgpu::ComputePipelineDescriptor desc;
     desc.compute.module = CreateShaderModule(R"(
diff --git a/third_party/emdawnwebgpu/pkg/webgpu/src/webgpu.cpp b/third_party/emdawnwebgpu/pkg/webgpu/src/webgpu.cpp
index d483e49..721a1e1 100644
--- a/third_party/emdawnwebgpu/pkg/webgpu/src/webgpu.cpp
+++ b/third_party/emdawnwebgpu/pkg/webgpu/src/webgpu.cpp
@@ -1537,12 +1537,12 @@
   mMapState = WGPUBufferMapState_Unmapped;
 
   FutureID futureId = mPendingMapRequest.futureID;
+  mPendingMapRequest = {};
   if (futureId == kNullFutureId) {
     // If we were mappedAtCreation, then there is no pending map request so we
     // don't need to resolve any futures.
     return;
   }
-  mPendingMapRequest = {};
   GetEventManager().SetFutureReady<MapAsyncEvent>(
       futureId, WGPUMapAsyncStatus_Aborted, message);
 }