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

Function unlinkClient

src/networking.cpp:1518–1599  ·  view source on GitHub ↗

Remove the specified client from global lists where the client could * be referenced, not including the Pub/Sub channels. * This is used by freeClient() and replicationCacheMaster(). */

Source from the content-addressed store, hash-verified

1516 * be referenced, not including the Pub/Sub channels.
1517 * This is used by freeClient() and replicationCacheMaster(). */
1518void unlinkClient(client *c) {
1519 listNode *ln;
1520 AssertCorrectThread(c);
1521 serverAssert(c->conn == nullptr || GlobalLocksAcquired());
1522 serverAssert(c->conn == nullptr || c->lock.fOwnLock());
1523
1524 /* If this is marked as current client unset it. */
1525 if (serverTL && serverTL->current_client == c) serverTL->current_client = NULL;
1526
1527 /* Certain operations must be done only if the client has an active connection.
1528 * If the client was already unlinked or if it's a "fake client" the
1529 * conn is already set to NULL. */
1530 if (c->conn) {
1531 /* Remove from the list of active clients. */
1532 if (c->client_list_node) {
1533 uint64_t id = htonu64(c->id);
1534 raxRemove(g_pserver->clients_index,(unsigned char*)&id,sizeof(id),NULL);
1535 listDelNode(g_pserver->clients,c->client_list_node);
1536 c->client_list_node = NULL;
1537 }
1538
1539 /* Check if this is a replica waiting for diskless replication (rdb pipe),
1540 * in which case it needs to be cleaned from that list */
1541 if (c->flags & CLIENT_SLAVE &&
1542 c->replstate == SLAVE_STATE_WAIT_BGSAVE_END &&
1543 g_pserver->rdb_pipe_conns)
1544 {
1545 int i;
1546 for (i=0; i < g_pserver->rdb_pipe_numconns; i++) {
1547 if (g_pserver->rdb_pipe_conns[i] == c->conn) {
1548 rdbPipeWriteHandlerConnRemoved(c->conn);
1549 g_pserver->rdb_pipe_conns[i] = NULL;
1550 break;
1551 }
1552 }
1553 }
1554 connClose(c->conn);
1555 c->conn = NULL;
1556 atomicDecr(g_pserver->rgthreadvar[c->iel].cclients, 1);
1557 }
1558
1559 /* Remove from the list of pending writes if needed. */
1560 if (c->flags & CLIENT_PENDING_WRITE) {
1561 std::unique_lock<fastlock> lockf(g_pserver->rgthreadvar[c->iel].lockPendingWrite);
1562 auto itr = std::find(g_pserver->rgthreadvar[c->iel].clients_pending_write.begin(),
1563 g_pserver->rgthreadvar[c->iel].clients_pending_write.end(), c);
1564 serverAssert(itr != g_pserver->rgthreadvar[c->iel].clients_pending_write.end());
1565 g_pserver->rgthreadvar[c->iel].clients_pending_write.erase(itr);
1566 c->flags &= ~CLIENT_PENDING_WRITE;
1567 }
1568
1569 /* When client was just unblocked because of a blocking operation,
1570 * remove it from the list of unblocked clients. */
1571 if (c->flags & CLIENT_UNBLOCKED) {
1572 ln = listSearchKey(g_pserver->rgthreadvar[c->iel].unblocked_clients,c);
1573 serverAssert(ln != NULL);
1574 listDelNode(g_pserver->rgthreadvar[c->iel].unblocked_clients,ln);
1575 c->flags &= ~CLIENT_UNBLOCKED;

Callers 4

replicationCacheMasterFunction · 0.85
freeClientFunction · 0.85

Calls 12

GlobalLocksAcquiredFunction · 0.85
raxRemoveFunction · 0.85
listDelNodeFunction · 0.85
connCloseFunction · 0.85
listSearchKeyFunction · 0.85
disableTrackingFunction · 0.85
fOwnLockMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
eraseMethod · 0.45

Tested by

no test coverage detected