)]}'
{
  "commit": "855fb4420197178d6a8398cc427c0d43bc23550e",
  "tree": "c7b6182735ef28ca83343f378cbfe5d5c91a6d90",
  "parents": [
    "a7538492d1ee34ec1c94f7643e5908bcb90a6cfc"
  ],
  "author": {
    "name": "Thomas Haller",
    "email": "thaller@redhat.com",
    "time": "Fri Apr 25 08:56:55 2025 +0200"
  },
  "committer": {
    "name": "Thomas Haller",
    "email": "thaller@redhat.com",
    "time": "Mon Nov 03 14:25:22 2025 +0100"
  },
  "message": "gbinding: use g_object_weak_ref_full for bindings\n\nThe pattern here is that we acquire strong references via GWeakRef.\nSo you might think that g_object_weak_unref() is safe to call.\n\nHowever, it is not safe, in case where another thread might run\ng_object_run_dispose(). Which is clear, because GWeakRef only ensures we\nhold a strong reference, but g_object_run_dispose() is anyway run on an\nobject where we already hold a reference.\n\nIn weak_unbind(), we obtain strong references, but (after) that\npoint, another thead might call g_object_run_dispose(). Then,\ninside unbind_internal_locked() we do:\n\n          g_object_weak_unref (source, weak_unbind, context);\n          binding_context_unref (context);\n\nNote that here weak_unbind might have already be unrefed, and\ng_object_weak_unref() fails an assertion. But worse, the\nweak_unbind callback will also be called and we issue two\nbinding_context_unref() and crash.\n\nThis is fixed by using g_object_weak_ref_full() (which handles the case\nthat the weak notification might have already be emitted) and a separate\nGDestroyNotify (that is guaranteed to run exactly once).\n\nThis still doesn\u0027t make it fully work. Note that we also call\n\n  g_signal_handler_disconnect (source, binding-\u003esource_notify);\n\nthis has exactly the same problem. A concurrent g_object_run_dispose()\nwill already disconnect all signal handlers, and calling disconnect\nfails an assertion. I think the solution for that is a new API\ng_signal_handler_try_disconnect(), which does not assert. After all, the\ngulong signal ID is unique (the gulong is large enough to never wrap and\nthere is even a g_error() check against that).\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "193bd5c28ff2fa988d0101735bb60cc80edc528a",
      "old_mode": 33188,
      "old_path": "gobject/gbinding.c",
      "new_id": "10739df50abcfed5c2831a0e4adcbf9dea52f1bb",
      "new_mode": 33188,
      "new_path": "gobject/gbinding.c"
    }
  ]
}
