X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/834ef78e27a8690a91d727259aaece611664a368..4a7893ca9ce334f2a144faa96ef02113bef4b2b2:/src/networking.c?ds=sidebyside diff --git a/src/networking.c b/src/networking.c index da0cd0a1..f37ecac1 100644 --- a/src/networking.c +++ b/src/networking.c @@ -62,6 +62,7 @@ redisClient *createClient(int fd) { } int _ensureFileEvent(redisClient *c) { + if (c->fd <= 0) return REDIS_ERR; if (c->bufpos == 0 && listLength(c->reply) == 0 && (c->replstate == REDIS_REPL_NONE || c->replstate == REDIS_REPL_ONLINE) && @@ -127,7 +128,11 @@ void addReply(redisClient *c, robj *obj) { } void addReplySds(redisClient *c, sds s) { - if (_ensureFileEvent(c) != REDIS_OK) return; + if (_ensureFileEvent(c) != REDIS_OK) { + /* The caller expects the sds to be free'd. */ + sdsfree(s); + return; + } if (sdslen(s) < REDIS_REPLY_CHUNK_THRESHOLD) { _addReplyStringToBuffer(c,s,sdslen(s)); sdsfree(s); @@ -145,6 +150,34 @@ void addReplyString(redisClient *c, char *s, size_t len) { } } +/* Adds an empty object to the reply list that will contain the multi bulk + * length, which is not known when this function is called. */ +void *addDeferredMultiBulkLength(redisClient *c) { + if (_ensureFileEvent(c) != REDIS_OK) return NULL; + _addReplyObjectToList(c,createObject(REDIS_STRING,NULL)); + return listLast(c->reply); +} + +/* Populate the length object and try glueing it to the next chunk. */ +void setDeferredMultiBulkLength(redisClient *c, void *node, long length) { + listNode *ln = (listNode*)node; + robj *len, *next; + + /* Abort when *node is NULL (see addDeferredMultiBulkLength). */ + if (node == NULL) return; + + len = listNodeValue(ln); + len->ptr = sdscatprintf(sdsempty(),"*%ld\r\n",length); + if (ln->next != NULL) { + next = listNodeValue(ln->next); + /* Only glue when the next node is a reply chunk. */ + if (next->type == REDIS_REPLY_NODE) { + len->ptr = sdscatlen(len->ptr,next->ptr,sdslen(next->ptr)); + listDelNode(c->reply,ln->next); + } + } +} + void addReplyDouble(redisClient *c, double d) { char dbuf[128], sbuf[128]; int dlen, slen; @@ -167,8 +200,8 @@ void addReplyLongLong(redisClient *c, long long ll) { _addReplyLongLong(c,ll,':'); } -void addReplyUlong(redisClient *c, unsigned long ul) { - _addReplyLongLong(c,(long long)ul,':'); +void addReplyMultiBulkLen(redisClient *c, long length) { + _addReplyLongLong(c,length,'*'); } void addReplyBulkLen(redisClient *c, robj *obj) {