void resetClient(ugClient *c) { if (c->argc) { freeClientArgv(c); zfree(c->argv); c->argv = NULL; } c->cmd = NULL; c->multibulklen = 0; c->reqtype = 0; c->bulklen = -1; }
void freeClient(client *c) { listNode *ln; if (c->flags & CLIENT_BLOCKED) { if (c->bfree) c->bfree(c->bpop.data); } /* If this is marked as current client unset it */ if (server.current_client == c) server.current_client = NULL; /* Free the query buffer */ sdsfree(c->querybuf); c->querybuf = NULL; /* Close socket, unregister events, and remove list of replies and * accumulated arguments. */ if (c->fd != -1) { aeDeleteFileEvent(server.el,c->fd,AE_READABLE); aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE); close(c->fd); } freeClientArgv(c); /* Remove from the list of clients */ if (c->fd != -1) { ln = listSearchKey(server.clients,c); serverAssert(ln != NULL); listDelNode(server.clients,ln); } /* If this client was scheduled for async freeing we need to remove it * from the queue. */ if (c->flags & CLIENT_CLOSE_ASAP) { ln = listSearchKey(server.clients_to_close,c); serverAssert(ln != NULL); listDelNode(server.clients_to_close,ln); } /* Release other dynamically allocated client structure fields, * and finally release the client structure itself. */ free(c->argv); free(c); }
/* resetClient prepare the client to process the next command */ void resetClient(redisClient *c) { freeClientArgv(c); c->bulklen = -1; c->multibulk = 0; }
void freeClient(redisClient *c) { listNode *ln; /* Note that if the client we are freeing is blocked into a blocking * call, we have to set querybuf to NULL *before* to call * unblockClientWaitingData() to avoid processInputBuffer() will get * called. Also it is important to remove the file events after * this, because this call adds the READABLE event. */ sdsfree(c->querybuf); c->querybuf = NULL; if (c->flags & REDIS_BLOCKED) unblockClientWaitingData(c); /* UNWATCH all the keys */ unwatchAllKeys(c); listRelease(c->watched_keys); /* Unsubscribe from all the pubsub channels */ pubsubUnsubscribeAllChannels(c,0); pubsubUnsubscribeAllPatterns(c,0); dictRelease(c->pubsub_channels); listRelease(c->pubsub_patterns); /* Obvious cleanup */ aeDeleteFileEvent(server.el,c->fd,AE_READABLE); aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE); listRelease(c->reply); freeClientArgv(c); close(c->fd); /* Remove from the list of clients */ ln = listSearchKey(server.clients,c); redisAssert(ln != NULL); listDelNode(server.clients,ln); /* Remove from the list of clients waiting for swapped keys, or ready * to be restarted, but not yet woken up again. */ if (c->flags & REDIS_IO_WAIT) { redisAssert(server.vm_enabled); if (listLength(c->io_keys) == 0) { ln = listSearchKey(server.io_ready_clients,c); /* When this client is waiting to be woken up (REDIS_IO_WAIT), * it should be present in the list io_ready_clients */ redisAssert(ln != NULL); listDelNode(server.io_ready_clients,ln); } else { while (listLength(c->io_keys)) { ln = listFirst(c->io_keys); dontWaitForSwappedKey(c,ln->value); } } server.vm_blocked_clients--; } listRelease(c->io_keys); /* Master/slave cleanup. * Case 1: we lost the connection with a slave. */ if (c->flags & REDIS_SLAVE) { if (c->replstate == REDIS_REPL_SEND_BULK && c->repldbfd != -1) close(c->repldbfd); list *l = (c->flags & REDIS_MONITOR) ? server.monitors : server.slaves; ln = listSearchKey(l,c); redisAssert(ln != NULL); listDelNode(l,ln); } /* Case 2: we lost the connection with the master. */ if (c->flags & REDIS_MASTER) { server.master = NULL; server.replstate = REDIS_REPL_CONNECT; /* Since we lost the connection with the master, we should also * close the connection with all our slaves if we have any, so * when we'll resync with the master the other slaves will sync again * with us as well. Note that also when the slave is not connected * to the master it will keep refusing connections by other slaves. */ while (listLength(server.slaves)) { ln = listFirst(server.slaves); freeClient((redisClient*)ln->value); } } /* Release memory */ zfree(c->argv); zfree(c->mbargv); freeClientMultiState(c); zfree(c); }
void freeClient(redisClient *c) { listNode *ln; /* Note that if the client we are freeing is blocked into a blocking * call, we have to set querybuf to NULL *before* to call * unblockClientWaitingData() to avoid processInputBuffer() will get * called. Also it is important to remove the file events after * this, because this call adds the READABLE event. */ sdsfree(c->querybuf); c->querybuf = NULL; if (c->flags & REDIS_BLOCKED) unblockClientWaitingData(c); /* UNWATCH all the keys */ unwatchAllKeys(c); listRelease(c->watched_keys); /* Unsubscribe from all the pubsub channels */ pubsubUnsubscribeAllChannels(c,0); pubsubUnsubscribeAllPatterns(c,0); dictRelease(c->pubsub_channels); listRelease(c->pubsub_patterns); /* Obvious cleanup */ aeDeleteFileEvent(server.el,c->fd,AE_READABLE); aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE); listRelease(c->reply); freeClientArgv(c); close(c->fd); /* Remove from the list of clients */ ln = listSearchKey(server.clients,c); redisAssert(ln != NULL); listDelNode(server.clients,ln); /* Remove from the list of clients that are now ready to be restarted * after waiting for swapped keys */ if (c->flags & REDIS_IO_WAIT && listLength(c->io_keys) == 0) { ln = listSearchKey(server.io_ready_clients,c); if (ln) { listDelNode(server.io_ready_clients,ln); server.vm_blocked_clients--; } } /* Remove from the list of clients waiting for swapped keys */ while (server.vm_enabled && listLength(c->io_keys)) { ln = listFirst(c->io_keys); dontWaitForSwappedKey(c,ln->value); } listRelease(c->io_keys); /* Master/slave cleanup */ if (c->flags & REDIS_SLAVE) { if (c->replstate == REDIS_REPL_SEND_BULK && c->repldbfd != -1) close(c->repldbfd); list *l = (c->flags & REDIS_MONITOR) ? server.monitors : server.slaves; ln = listSearchKey(l,c); redisAssert(ln != NULL); listDelNode(l,ln); } if (c->flags & REDIS_MASTER) { server.master = NULL; server.replstate = REDIS_REPL_CONNECT; } /* Release memory */ zfree(c->argv); zfree(c->mbargv); freeClientMultiState(c); zfree(c); }
/* resetClient prepare the client to process the next command */ void resetClient(client *c) { freeClientArgv(c); c->reqtype = 0; c->multibulklen = 0; c->bulklen = -1; }