From f15e715b6f92d3d87df0c089e262c9f56f3d7c3b Mon Sep 17 00:00:00 2001 From: Johnathan Becker Date: Mon, 18 May 2026 13:04:45 -0600 Subject: [PATCH] Fix atomic property setters held spinlock during release causing deadlocks --- properties.mm | 19 ++++++++++++------- spinlock.h | 10 +++++----- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/properties.mm b/properties.mm index 7c8446a8..0be2922c 100644 --- a/properties.mm +++ b/properties.mm @@ -79,9 +79,12 @@ void objc_setProperty_atomic(id obj, SEL _cmd, id arg, ptrdiff_t offset) char *addr = (char*)obj; addr += offset; arg = objc_retain(arg); - auto guard = acquire_locks_for_pointers(addr); - id old = *(id*)addr; - *(id*)addr = arg; + id old; + { + auto guard = acquire_locks_for_pointers(addr); + old = *(id*)addr; + *(id*)addr = arg; + } objc_release(old); } @@ -90,11 +93,13 @@ void objc_setProperty_atomic_copy(id obj, SEL _cmd, id arg, ptrdiff_t offset) { char *addr = (char*)obj; addr += offset; - arg = [arg copy]; - auto guard = acquire_locks_for_pointers(addr); - id old = *(id*)addr; - *(id*)addr = arg; + id old; + { + auto guard = acquire_locks_for_pointers(addr); + old = *(id*)addr; + *(id*)addr = arg; + } objc_release(old); } diff --git a/spinlock.h b/spinlock.h index f707d6a6..169c5a0f 100644 --- a/spinlock.h +++ b/spinlock.h @@ -121,14 +121,14 @@ class DoubleLockGuard public: DoubleLockGuard(ThinLock *lock1, ThinLock *lock2) : lock1(lock1), lock2(lock2) { - if (lock2 < lock1) + if (this->lock2 < this->lock1) { - std::swap(lock1, lock2); + std::swap(this->lock1, this->lock2); } - lock1->lock(); - if (lock1 != lock2) + this->lock1->lock(); + if (this->lock1 != this->lock2) { - lock2->lock(); + this->lock2->lock(); } } ~DoubleLockGuard()