Fix lock inversion in processEventsWhileBlocked
Former-commit-id: a9249d4a82a0f0355ac8ffa40b34b9c14cabf66b
This commit is contained in:
parent
87626299a6
commit
4d5d7ed59f
@ -1630,12 +1630,12 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
|
|||||||
if (writeToClient(fd,c,1) == C_ERR)
|
if (writeToClient(fd,c,1) == C_ERR)
|
||||||
{
|
{
|
||||||
AeLocker ae;
|
AeLocker ae;
|
||||||
c->lock();
|
c->lock.lock();
|
||||||
ae.arm(c);
|
ae.arm(c);
|
||||||
if (c->flags & CLIENT_CLOSE_ASAP)
|
if (c->flags & CLIENT_CLOSE_ASAP)
|
||||||
{
|
{
|
||||||
if (!freeClient(c))
|
if (!freeClient(c))
|
||||||
c->unlock();
|
c->lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3107,13 +3107,24 @@ int processEventsWhileBlocked(int iel) {
|
|||||||
int iterations = 4; /* See the function top-comment. */
|
int iterations = 4; /* See the function top-comment. */
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
client *c = serverTL->current_client;
|
std::vector<client*> vecclients;
|
||||||
if (c != nullptr)
|
listIter li;
|
||||||
|
listNode *ln;
|
||||||
|
listRewind(g_pserver->clients, &li);
|
||||||
|
|
||||||
|
// All client locks must be acquired *after* the global lock is reacquired to prevent deadlocks
|
||||||
|
// so unlock here, and save them for reacquisition later
|
||||||
|
while ((ln = listNext(&li)) != nullptr)
|
||||||
{
|
{
|
||||||
serverAssert(c->flags & CLIENT_PROTECTED);
|
client *c = (client*)listNodeValue(ln);
|
||||||
c->lock.unlock();
|
if (c->lock.fOwnLock()) {
|
||||||
|
serverAssert(c->flags & CLIENT_PROTECTED); // If the client is not protected we have no gurantee they won't be free'd in the event loop
|
||||||
|
c->lock.unlock();
|
||||||
|
vecclients.push_back(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
aeReleaseLock();
|
aeReleaseLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -3129,18 +3140,18 @@ int processEventsWhileBlocked(int iel) {
|
|||||||
{
|
{
|
||||||
// Caller expects us to be locked so fix and rethrow
|
// Caller expects us to be locked so fix and rethrow
|
||||||
AeLocker locker;
|
AeLocker locker;
|
||||||
if (c != nullptr)
|
locker.arm(nullptr);
|
||||||
c->lock.lock();
|
|
||||||
locker.arm(c);
|
|
||||||
locker.release();
|
locker.release();
|
||||||
|
for (client *c : vecclients)
|
||||||
|
c->lock.lock();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
AeLocker locker;
|
AeLocker locker;
|
||||||
if (c != nullptr)
|
locker.arm(nullptr);
|
||||||
c->lock.lock();
|
|
||||||
locker.arm(c);
|
|
||||||
locker.release();
|
locker.release();
|
||||||
|
for (client *c : vecclients)
|
||||||
|
c->lock.lock();
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user