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(). */
| 1237 | * be referenced, not including the Pub/Sub channels. |
| 1238 | * This is used by freeClient() and replicationCacheMaster(). */ |
| 1239 | void unlinkClient(client *c) { |
| 1240 | listNode *ln; |
| 1241 | |
| 1242 | /* If this is marked as current client unset it. */ |
| 1243 | if (server.current_client == c) server.current_client = NULL; |
| 1244 | |
| 1245 | /* Certain operations must be done only if the client has an active connection. |
| 1246 | * If the client was already unlinked or if it's a "fake client" the |
| 1247 | * conn is already set to NULL. */ |
| 1248 | if (c->conn) { |
| 1249 | /* Remove from the list of active clients. */ |
| 1250 | if (c->client_list_node) { |
| 1251 | uint64_t id = htonu64(c->id); |
| 1252 | raxRemove(server.clients_index,(unsigned char*)&id,sizeof(id),NULL); |
| 1253 | listDelNode(server.clients,c->client_list_node); |
| 1254 | c->client_list_node = NULL; |
| 1255 | } |
| 1256 | |
| 1257 | /* Check if this is a replica waiting for diskless replication (rdb pipe), |
| 1258 | * in which case it needs to be cleaned from that list */ |
| 1259 | if (c->flags & CLIENT_SLAVE && |
| 1260 | c->replstate == SLAVE_STATE_WAIT_BGSAVE_END && |
| 1261 | server.rdb_pipe_conns) |
| 1262 | { |
| 1263 | int i; |
| 1264 | for (i=0; i < server.rdb_pipe_numconns; i++) { |
| 1265 | if (server.rdb_pipe_conns[i] == c->conn) { |
| 1266 | rdbPipeWriteHandlerConnRemoved(c->conn); |
| 1267 | server.rdb_pipe_conns[i] = NULL; |
| 1268 | break; |
| 1269 | } |
| 1270 | } |
| 1271 | } |
| 1272 | connClose(c->conn); |
| 1273 | c->conn = NULL; |
| 1274 | } |
| 1275 | |
| 1276 | /* Remove from the list of pending writes if needed. */ |
| 1277 | if (c->flags & CLIENT_PENDING_WRITE) { |
| 1278 | ln = listSearchKey(server.clients_pending_write,c); |
| 1279 | serverAssert(ln != NULL); |
| 1280 | listDelNode(server.clients_pending_write,ln); |
| 1281 | c->flags &= ~CLIENT_PENDING_WRITE; |
| 1282 | } |
| 1283 | |
| 1284 | /* Remove from the list of pending reads if needed. */ |
| 1285 | if (c->flags & CLIENT_PENDING_READ) { |
| 1286 | ln = listSearchKey(server.clients_pending_read,c); |
| 1287 | serverAssert(ln != NULL); |
| 1288 | listDelNode(server.clients_pending_read,ln); |
| 1289 | c->flags &= ~CLIENT_PENDING_READ; |
| 1290 | } |
| 1291 | |
| 1292 | /* When client was just unblocked because of a blocking operation, |
| 1293 | * remove it from the list of unblocked clients. */ |
| 1294 | if (c->flags & CLIENT_UNBLOCKED) { |
| 1295 | ln = listSearchKey(server.unblocked_clients,c); |
| 1296 | serverAssert(ln != NULL); |
no test coverage detected