diff options
Diffstat (limited to 'src/networking.c')
-rw-r--r-- | src/networking.c | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/src/networking.c b/src/networking.c index bf39c6582..e8a93dde3 100644 --- a/src/networking.c +++ b/src/networking.c @@ -2785,7 +2785,7 @@ sds catClientInfoString(sds s, client *client) { } sds ret = sdscatfmt(s, - "id=%U addr=%s laddr=%s %s name=%s age=%I idle=%I flags=%s db=%i sub=%i psub=%i multi=%i qbuf=%U qbuf-free=%U argv-mem=%U multi-mem=%U rbs=%U rbp=%U obl=%U oll=%U omem=%U tot-mem=%U events=%s cmd=%s user=%s redir=%I resp=%i", + "id=%U addr=%s laddr=%s %s name=%s age=%I idle=%I flags=%s db=%i sub=%i psub=%i ssub=%i multi=%i qbuf=%U qbuf-free=%U argv-mem=%U multi-mem=%U rbs=%U rbp=%U obl=%U oll=%U omem=%U tot-mem=%U events=%s cmd=%s user=%s redir=%I resp=%i", (unsigned long long) client->id, getClientPeerId(client), getClientSockname(client), @@ -2797,6 +2797,7 @@ sds catClientInfoString(sds s, client *client) { client->db->id, (int) dictSize(client->pubsub_channels), (int) listLength(client->pubsub_patterns), + (int) dictSize(client->pubsubshard_channels), (client->flags & CLIENT_MULTI) ? client->mstate.count : -1, (unsigned long long) sdslen(client->querybuf), (unsigned long long) sdsavail(client->querybuf), @@ -2832,18 +2833,9 @@ sds getAllClientsInfoString(int type) { return o; } -/* This function implements CLIENT SETNAME, including replying to the - * user with an error if the charset is wrong (in that case C_ERR is - * returned). If the function succeeded C_OK is returned, and it's up - * to the caller to send a reply if needed. - * - * Setting an empty string as name has the effect of unsetting the - * currently set name: the client will remain unnamed. - * - * This function is also used to implement the HELLO SETNAME option. */ -int clientSetNameOrReply(client *c, robj *name) { - int len = sdslen(name->ptr); - char *p = name->ptr; +/* Returns C_OK if the name has been set or C_ERR if the name is invalid. */ +int clientSetName(client *c, robj *name) { + int len = (name != NULL) ? sdslen(name->ptr) : 0; /* Setting the client name to an empty string actually removes * the current name. */ @@ -2856,11 +2848,9 @@ int clientSetNameOrReply(client *c, robj *name) { /* Otherwise check if the charset is ok. We need to do this otherwise * CLIENT LIST format will break. You should always be able to * split by space to get the different fields. */ + char *p = name->ptr; for (int j = 0; j < len; j++) { if (p[j] < '!' || p[j] > '~') { /* ASCII is assumed. */ - addReplyError(c, - "Client names cannot contain spaces, " - "newlines or special characters."); return C_ERR; } } @@ -2870,6 +2860,25 @@ int clientSetNameOrReply(client *c, robj *name) { return C_OK; } +/* This function implements CLIENT SETNAME, including replying to the + * user with an error if the charset is wrong (in that case C_ERR is + * returned). If the function succeeded C_OK is returned, and it's up + * to the caller to send a reply if needed. + * + * Setting an empty string as name has the effect of unsetting the + * currently set name: the client will remain unnamed. + * + * This function is also used to implement the HELLO SETNAME option. */ +int clientSetNameOrReply(client *c, robj *name) { + int result = clientSetName(c, name); + if (result == C_ERR) { + addReplyError(c, + "Client names cannot contain spaces, " + "newlines or special characters."); + } + return result; +} + /* Reset the client state to resemble a newly connected client. */ void resetCommand(client *c) { @@ -3660,9 +3669,7 @@ size_t getClientMemoryUsage(client *c, size_t *output_buffer_mem_usage) { /* Add memory overhead of pubsub channels and patterns. Note: this is just the overhead of the robj pointers * to the strings themselves because they aren't stored per client. */ - mem += listLength(c->pubsub_patterns) * sizeof(listNode); - mem += dictSize(c->pubsub_channels) * sizeof(dictEntry) + - dictSlots(c->pubsub_channels) * sizeof(dictEntry*); + mem += pubsubMemOverhead(c); /* Add memory overhead of the tracking prefixes, this is an underestimation so we don't need to traverse the entire rax */ if (c->client_tracking_prefixes) @@ -3997,10 +4004,15 @@ void processEventsWhileBlocked(void) { * ========================================================================== */ #define IO_THREADS_MAX_NUM 128 +#define CACHE_LINE_SIZE 64 + +typedef struct __attribute__((aligned(CACHE_LINE_SIZE))) threads_pending { + redisAtomic unsigned long value; +} threads_pending; pthread_t io_threads[IO_THREADS_MAX_NUM]; pthread_mutex_t io_threads_mutex[IO_THREADS_MAX_NUM]; -redisAtomic unsigned long io_threads_pending[IO_THREADS_MAX_NUM]; +threads_pending io_threads_pending[IO_THREADS_MAX_NUM]; int io_threads_op; /* IO_THREADS_OP_IDLE, IO_THREADS_OP_READ or IO_THREADS_OP_WRITE. */ // TODO: should access to this be atomic??! /* This is the list of clients each thread will serve when threaded I/O is @@ -4010,12 +4022,12 @@ list *io_threads_list[IO_THREADS_MAX_NUM]; static inline unsigned long getIOPendingCount(int i) { unsigned long count = 0; - atomicGetWithSync(io_threads_pending[i], count); + atomicGetWithSync(io_threads_pending[i].value, count); return count; } static inline void setIOPendingCount(int i, unsigned long count) { - atomicSetWithSync(io_threads_pending[i], count); + atomicSetWithSync(io_threads_pending[i].value, count); } void *IOThreadMain(void *myid) { |