MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / executeWithoutGlobalLock

Function executeWithoutGlobalLock

src/server.cpp:6900–6955  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6898}
6899
6900void executeWithoutGlobalLock(std::function<void()> func) {
6901 serverAssert(GlobalLocksAcquired());
6902
6903 std::vector<client*> vecclients;
6904 listIter li;
6905 listNode *ln;
6906 listRewind(g_pserver->clients, &li);
6907
6908 // All client locks must be acquired *after* the global lock is reacquired to prevent deadlocks
6909 // so unlock here, and save them for reacquisition later
6910 while ((ln = listNext(&li)) != nullptr)
6911 {
6912 client *c = (client*)listNodeValue(ln);
6913 if (c->lock.fOwnLock()) {
6914 serverAssert(c->flags & CLIENT_PROTECTED || c->flags & CLIENT_EXECUTING_COMMAND); // If the client is not protected we have no gurantee they won't be free'd in the event loop
6915 c->lock.unlock();
6916 vecclients.push_back(c);
6917 }
6918 }
6919
6920 /* Since we're about to release our lock we need to flush the repl backlog queue */
6921 bool fReplBacklog = g_pserver->repl_batch_offStart >= 0;
6922 if (fReplBacklog) {
6923 flushReplBacklogToClients();
6924 g_pserver->repl_batch_idxStart = -1;
6925 g_pserver->repl_batch_offStart = -1;
6926 }
6927
6928 aeReleaseLock();
6929 serverAssert(!GlobalLocksAcquired());
6930 try {
6931 func();
6932 }
6933 catch (...) {
6934 // Caller expects us to be locked so fix and rethrow
6935 AeLocker locker;
6936 locker.arm(nullptr);
6937 locker.release();
6938 for (client *c : vecclients)
6939 c->lock.lock();
6940 throw;
6941 }
6942
6943 AeLocker locker;
6944 locker.arm(nullptr);
6945 locker.release();
6946
6947 // Restore it so the calling code is not confused
6948 if (fReplBacklog) {
6949 g_pserver->repl_batch_idxStart = g_pserver->repl_backlog_idx;
6950 g_pserver->repl_batch_offStart = g_pserver->master_repl_offset;
6951 }
6952
6953 for (client *c : vecclients)
6954 c->lock.lock();
6955}
6956
6957/* purpose is one of CHILD_TYPE_ types */

Callers 1

Calls 10

GlobalLocksAcquiredFunction · 0.85
listRewindFunction · 0.85
listNextFunction · 0.85
aeReleaseLockFunction · 0.85
armMethod · 0.80
fOwnLockMethod · 0.45
unlockMethod · 0.45
releaseMethod · 0.45
lockMethod · 0.45

Tested by

no test coverage detected