MCPcopy Create free account
hub / github.com/F-Stack/f-stack / setDeferredReply

Function setDeferredReply

app/redis-6.2.6/src/networking.c:574–630  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

572}
573
574void setDeferredReply(client *c, void *node, const char *s, size_t length) {
575 listNode *ln = (listNode*)node;
576 clientReplyBlock *next, *prev;
577
578 /* Abort when *node is NULL: when the client should not accept writes
579 * we return NULL in addReplyDeferredLen() */
580 if (node == NULL) return;
581 serverAssert(!listNodeValue(ln));
582
583 /* Normally we fill this dummy NULL node, added by addReplyDeferredLen(),
584 * with a new buffer structure containing the protocol needed to specify
585 * the length of the array following. However sometimes there might be room
586 * in the previous/next node so we can instead remove this NULL node, and
587 * suffix/prefix our data in the node immediately before/after it, in order
588 * to save a write(2) syscall later. Conditions needed to do it:
589 *
590 * - The prev node is non-NULL and has space in it or
591 * - The next node is non-NULL,
592 * - It has enough room already allocated
593 * - And not too large (avoid large memmove) */
594 if (ln->prev != NULL && (prev = listNodeValue(ln->prev)) &&
595 prev->size - prev->used > 0)
596 {
597 size_t len_to_copy = prev->size - prev->used;
598 if (len_to_copy > length)
599 len_to_copy = length;
600 memcpy(prev->buf + prev->used, s, len_to_copy);
601 prev->used += len_to_copy;
602 length -= len_to_copy;
603 if (length == 0) {
604 listDelNode(c->reply, ln);
605 return;
606 }
607 s += len_to_copy;
608 }
609
610 if (ln->next != NULL && (next = listNodeValue(ln->next)) &&
611 next->size - next->used >= length &&
612 next->used < PROTO_REPLY_CHUNK_BYTES * 4)
613 {
614 memmove(next->buf + length, next->buf, next->used);
615 memcpy(next->buf, s, length);
616 next->used += length;
617 listDelNode(c->reply,ln);
618 } else {
619 /* Create a new node */
620 clientReplyBlock *buf = zmalloc(length + sizeof(clientReplyBlock));
621 /* Take over the allocation's internal fragmentation */
622 buf->size = zmalloc_usable_size(buf) - sizeof(clientReplyBlock);
623 buf->used = length;
624 memcpy(buf->buf, s, length);
625 listNodeValue(ln) = buf;
626 c->reply_bytes += buf->size;
627
628 closeClientOnOutputBufferLimitReached(c, 1);
629 }
630}
631

Callers 2

setDeferredAggregateLenFunction · 0.85
setDeferredReplyBulkSdsFunction · 0.85

Calls 6

listDelNodeFunction · 0.85
zmallocFunction · 0.85
zmalloc_usable_sizeFunction · 0.85
memcpyFunction · 0.50
memmoveFunction · 0.50

Tested by

no test coverage detected