diff --git a/src/ae.cpp b/src/ae.cpp index 99f09d49f..a78c4a7c2 100644 --- a/src/ae.cpp +++ b/src/ae.cpp @@ -803,9 +803,9 @@ void aeAcquireLock() g_lock.lock(); } -int aeTryAcquireLock() +int aeTryAcquireLock(bool fWeak) { - return g_lock.try_lock(); + return g_lock.try_lock(fWeak); } void aeReleaseLock() diff --git a/src/ae.h b/src/ae.h index f08c49dd8..6fd230da9 100644 --- a/src/ae.h +++ b/src/ae.h @@ -159,7 +159,7 @@ int aeGetSetSize(aeEventLoop *eventLoop); int aeResizeSetSize(aeEventLoop *eventLoop, int setsize); void aeAcquireLock(); -int aeTryAcquireLock(); +int aeTryAcquireLock(bool fWeak); void aeReleaseLock(); int aeThreadOwnsLock(); diff --git a/src/aelocker.h b/src/aelocker.h index 942f936c9..562ac55ef 100644 --- a/src/aelocker.h +++ b/src/aelocker.h @@ -16,19 +16,25 @@ public: serverAssert(!m_fArmed); serverAssert(c->lock.fOwnLock()); - bool fClientLocked = true; - while (!aeTryAcquireLock()) + if (!aeTryAcquireLock(true /*fWeak*/)) // avoid locking the client if we can { - if (fClientLocked) c->lock.unlock(); - fClientLocked = false; - aeAcquireLock(); - if (!c->lock.try_lock()) + bool fOwnClientLock = true; + for (;;) { - aeReleaseLock(); - } - else - { - break; + if (fOwnClientLock) + { + c->lock.unlock(); + fOwnClientLock = false; + } + aeAcquireLock(); + if (!c->lock.try_lock(false)) // ensure a strong try because aeAcquireLock is expensive + { + aeReleaseLock(); + } + else + { + break; + } } } diff --git a/src/fastlock.cpp b/src/fastlock.cpp index 6be725f6d..1340e087c 100644 --- a/src/fastlock.cpp +++ b/src/fastlock.cpp @@ -133,7 +133,7 @@ extern "C" void fastlock_lock(struct fastlock *lock) std::atomic_thread_fence(std::memory_order_acquire); } -extern "C" int fastlock_trylock(struct fastlock *lock) +extern "C" int fastlock_trylock(struct fastlock *lock, int fWeak) { if ((int)__atomic_load_4(&lock->m_pidOwner, __ATOMIC_ACQUIRE) == gettid()) { @@ -150,7 +150,7 @@ extern "C" int fastlock_trylock(struct fastlock *lock) struct ticket ticket_expect { active, active }; struct ticket ticket_setiflocked { active, next }; - if (__atomic_compare_exchange(&lock->m_ticket, &ticket_expect, &ticket_setiflocked, false /*weak*/, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)) + if (__atomic_compare_exchange(&lock->m_ticket, &ticket_expect, &ticket_setiflocked, fWeak /*weak*/, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { lock->m_depth = 1; __atomic_store_4(&lock->m_pidOwner, gettid(), __ATOMIC_RELEASE); @@ -181,8 +181,8 @@ extern "C" void fastlock_unlock(struct fastlock *lock) { assert((int)__atomic_load_4(&lock->m_pidOwner, __ATOMIC_RELAXED) >= 0); // unlock after free lock->m_pidOwner = -1; - std::atomic_thread_fence(std::memory_order_acquire); - uint16_t activeNew = __atomic_add_fetch(&lock->m_ticket.m_active, 1, __ATOMIC_ACQ_REL); // on x86 the atomic is not required here, but ASM handles that case + std::atomic_thread_fence(std::memory_order_release); + uint16_t activeNew = __atomic_add_fetch(&lock->m_ticket.m_active, 1, __ATOMIC_RELEASE); // on x86 the atomic is not required here, but ASM handles that case unlock_futex(lock, activeNew); } } diff --git a/src/fastlock.h b/src/fastlock.h index 81c5807cd..26a4b4d01 100644 --- a/src/fastlock.h +++ b/src/fastlock.h @@ -9,7 +9,7 @@ extern "C" { struct fastlock; void fastlock_init(struct fastlock *lock); void fastlock_lock(struct fastlock *lock); -int fastlock_trylock(struct fastlock *lock); +int fastlock_trylock(struct fastlock *lock, int fWeak); void fastlock_unlock(struct fastlock *lock); void fastlock_free(struct fastlock *lock); @@ -55,9 +55,9 @@ struct fastlock fastlock_lock(this); } - bool try_lock() + bool try_lock(bool fWeak = false) { - return !!fastlock_trylock(this); + return !!fastlock_trylock(this, fWeak); } void unlock() diff --git a/src/networking.cpp b/src/networking.cpp index 0159ba9f9..76d07a117 100644 --- a/src/networking.cpp +++ b/src/networking.cpp @@ -1475,7 +1475,7 @@ int writeToClient(int fd, client *c, int handler_installed) { serverLog(LL_VERBOSE, "Error writing to client: %s", strerror(errno)); lock.unlock(); - if (aeTryAcquireLock()) + if (aeTryAcquireLock(true /*fWeak*/)) { freeClient(c); aeReleaseLock(); @@ -1502,7 +1502,7 @@ int writeToClient(int fd, client *c, int handler_installed) { /* Close connection after entire reply has been sent. */ if (c->flags & CLIENT_CLOSE_AFTER_REPLY) { lock.unlock(); - if (aeTryAcquireLock()) + if (aeTryAcquireLock(true /*fWeak*/)) { freeClient(c); aeReleaseLock();