)]}'
{
  "commit": "0c091e722563f2e427f2ddc9c84080d1f95eb11c",
  "tree": "154813cc9b7ef4f7d972af47a3cd620bad4af6d5",
  "parents": [
    "97d6c8ffa5925691d97e7bcb52fbf36fcd300b50"
  ],
  "author": {
    "name": "Lokbondo Kung",
    "email": "lokokung@google.com",
    "time": "Tue Jul 14 14:40:13 2026 -0700"
  },
  "committer": {
    "name": "dawn-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "email": "dawn-scoped@luci-project-accounts.iam.gserviceaccount.com",
    "time": "Tue Jul 14 14:40:13 2026 -0700"
  },
  "message": "[wire] Fix some other lock-inversions with client Buffers.\n\n- This fixes two more lock-inversion cases that weren\u0027t\n  caught in:\n  https://dawn-review.git.corp.google.com/c/dawn/+/321995.\n  Specifically:\n  1) One lock inversion was a result of calling MapAsyncEvent\u0027s\n     ReadyHook while also holding the EventManager\u0027s mTrackedEvents\n     lock. The inversion happens when a user\u0027s MapAsync callback\n     calls MapAsync inside itself which, while holding the Buffer\n     lock, now tries to acquire mTrackedEvent\u0027s lock. This change\n     ensures that ReadyHook is called while we are not holding the\n     mTrackedEvent\u0027s lock so that those two locks are always\n     acquired with the Buffer lock first.\n  2) Another lock inversion happens in our end2end tests because\n     we synchronously mock the wire with the TerribleCommandBuffer\n     in those tests. This case shouldn\u0027t cause an issue in\n     production because it is a result of the TerribleCommandBuffer\n     blocking synchronously and calling Flush as a part of\n     GetCmdSpace. In Chromium, the Flush wouldn\u0027t be blocking since\n     it would be an IPC back to the server, but in our tests, it\n     happens while holding any locks on the client side,\n     specifically, this inversion can happen when:\n     Let M0 be the buffer-\u003emState lock,\n         M1 be the server-wide lock from server-\u003eGetGuard()\n         M2 be a native lock, in this case the call_once in\n\t    native::Buffer::MapAsyncBufferEvent::Complete.\n     The inversion proposed by TSAN assumes the following happens:\n     - Thread 1 calls something like Client::Buffer::Unmap which\n       takes M0, then flushes to the server trying to take M1.\n     - Thread 2 calls a server-side callback handler, i.e.\n       OnBufferMapAsync which starts with M1 taken, then in the\n       native code tries to takes M2.\n     - Thread 3 calls native::MapAsyncEvent::Complete which takes\n       M2, then triggers server-\u003eclient response which calls the\n       client::Buffer::MapAsyncEvent::ReadyHook which tries to\n       take M0.\n     With those three things happening, then we could have a\n     deadlock. To address this, we made sure that the\n     client-\u003eSerializeCommand calls are called without holding\n     buffer-\u003emState lock. This also required making the\n     memoryHandle a shared_ptr for now so that we could\n     properly serialize the memoryHandle data while being sure\n     that the handle was still valid.\n\nBug: 529413629\nChange-Id: I561190c76bd26607193e9f847e5cb89744a0a3c4\nReviewed-on: https://dawn-review.googlesource.com/c/dawn/+/323497\nReviewed-by: Kai Ninomiya \u003ckainino@chromium.org\u003e\nCommit-Queue: Loko Kung \u003clokokung@google.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "22cbfc7aceb42e5fe460a68b3317edfa89e40a00",
      "old_mode": 33188,
      "old_path": "src/dawn/wire/client/Buffer.cpp",
      "new_id": "143c6ff48d778153bab76b4d84f7cad6b94f3f5e",
      "new_mode": 33188,
      "new_path": "src/dawn/wire/client/Buffer.cpp"
    },
    {
      "type": "modify",
      "old_id": "a2d5dbdd09835be0a67b421a7d8e18238abce290",
      "old_mode": 33188,
      "old_path": "src/dawn/wire/client/Buffer.h",
      "new_id": "cf879047a325571c56cf494f324936359406847b",
      "new_mode": 33188,
      "new_path": "src/dawn/wire/client/Buffer.h"
    },
    {
      "type": "modify",
      "old_id": "7c5f74c7effe279408e35ffdc8143624a1bc6a5c",
      "old_mode": 33188,
      "old_path": "src/dawn/wire/client/Device.cpp",
      "new_id": "f9b9f916e204cc880921e5991e245cef5f912710",
      "new_mode": 33188,
      "new_path": "src/dawn/wire/client/Device.cpp"
    },
    {
      "type": "modify",
      "old_id": "98bf46b57dbdd183d0a1626f8e10223382ddff37",
      "old_mode": 33188,
      "old_path": "src/dawn/wire/client/EventManager.h",
      "new_id": "edba2ca0426861af0677060e97c77e73db5f7c82",
      "new_mode": 33188,
      "new_path": "src/dawn/wire/client/EventManager.h"
    }
  ]
}
