)]}'
{
  "commit": "80f435b8c79b4cab35b1151da1a6b768d19aa70d",
  "tree": "7b00cf878c89cd525c503efa798078fb65a7f57b",
  "parents": [
    "8d16d2084a37adc5ce400dc3411386ae38bfd365"
  ],
  "author": {
    "name": "Trim21",
    "email": "trim21.me@gmail.com",
    "time": "Tue Sep 15 17:06:41 2026 +0800"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Tue Sep 15 02:06:41 2026 -0700"
  },
  "message": "fix: re-acquire the GIL in class_::init_instance before instance registration (#6172)\n\n* fix: re-acquire GIL in init_instance for thread-safe instance registration\n\nWith a factory-based py::init combined with py::call_guard\u003cpy::gil_scoped_release\u003e,\ninit_instance -\u003e register_instance runs while the GIL is released, racing on\ninternals.registered_instances with GIL-holding threads. This corrupts the\ninstance map and leads to \u0027pybind11_object_dealloc(): Tried to deallocate\nunregistered instance!\u0027 -\u003e std::terminate. Acquire the GIL (no-op if already\nheld) in both class_::init_instance overloads; free-threaded builds keep using\ntheir sharded mutex and are unaffected.\n\n* tests: avoid std::make_unique in test_gil_scoped (C++14 only)\n\nThe iOS/Android wheel CI jobs build the test suite with -std\u003dgnu++11.\n\n* tests: skip test_init_factory_gil_released_concurrent_construction on free-threaded builds\n\nOn free-threaded builds py::gil_scoped_release detaches the thread state and the\nconstructor machinery is not safe when called detached, so the test segfaults\n(pre-existing limitation of call_guard\u003cgil_scoped_release\u003e, unrelated to the\ninit_instance fix). The instance map is mutex-protected on free-threaded builds\nanyway, so there is nothing to test there. An early return inside the function\ncovers the _run_in_process parametrizations, where pytest skip markers do not\napply.\n\n* tests: run the init_instance race regression only as a direct test\n\nThe test was in ALL_BASIC_TESTS, so it also ran in the _run_in_process\nparametrizations, whose subprocesses impose a 10s timeout; on Windows\n(sequential variant) the extra sleep timer granularity and GIL handoff\noverhead pushed that over the limit. It is a data-race regression, not a\ndeadlock check, so define it after ALL_BASIC_TESTS like the\ntest_run_in_process_* functions and drop the now-unneeded free-threaded\nearly return.\n\n* chore: retrigger CI (GCC 9 job failed on apt 404 for python3-setuptools, unrelated)\n\n* fix: make init_instance GIL acquisition unconditional\n\nThe `#if !defined(Py_GIL_DISABLED)` guards skipped the acquire on free-threaded builds, where `gil_scoped_release` detaches the thread state. `init_instance` then crashes in `PyCriticalSection_BeginMutex` (via `get_type_info`) even single-threaded, because the critical section requires an attached thread state.\n\n`gil_scoped_acquire` attaches the thread state without taking a global lock, so this is safe on free-threaded builds and does not serialize threads.\n\n* test: run init_instance regression on free-threaded builds too\n\nThe acquire in init_instance is now unconditional, so the regression test also covers the free-threaded detached-thread-state crash. Drop the PY_GIL_DISABLED skip.\n\n* docs: cover free-threaded thread-state attach in init_instance comments\n\nThe unconditional gil_scoped_acquire is also needed on free-threaded builds, where gil_scoped_release detaches the thread state and get_type_info requires it to be attached. Mention this in the init_instance comment and the regression-test docstring.",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "3687983460e474469c1d5d3193e76bc711b7f392",
      "old_mode": 33188,
      "old_path": "include/pybind11/pybind11.h",
      "new_id": "c57312d64d048be1f91ea4b0e223727591fed372",
      "new_mode": 33188,
      "new_path": "include/pybind11/pybind11.h"
    },
    {
      "type": "modify",
      "old_id": "f136086e842dacf5f913028061cb1b536a71446b",
      "old_mode": 33188,
      "old_path": "tests/test_gil_scoped.cpp",
      "new_id": "191284b1a8cc0b9b6874e93a6ad84f57fff22964",
      "new_mode": 33188,
      "new_path": "tests/test_gil_scoped.cpp"
    },
    {
      "type": "modify",
      "old_id": "fc998b0ed2a56e17aa2fad8192315791dc1668ae",
      "old_mode": 33188,
      "old_path": "tests/test_gil_scoped.py",
      "new_id": "8c0ac9597dd18883a5ee0b3e74d1959c26aa2496",
      "new_mode": 33188,
      "new_path": "tests/test_gil_scoped.py"
    }
  ]
}
