summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2017-07-04 11:55:05 +0200
committerantirez <antirez@gmail.com>2017-07-06 16:10:07 +0200
commit5c5e8a500c1c5095958f829b72536bd224eec4a0 (patch)
tree572436b381f47a50af85fb7da17f6a610b06c989
parentc63a97f8d24248258f058d97ffdd72be54c95e5d (diff)
downloadredis-5c5e8a500c1c5095958f829b72536bd224eec4a0.tar.gz
Add symmetrical assertion to track c->reply_buffer infinite growth.
Redis clients need to have an instantaneous idea of the amount of memory they are consuming (if the number is not exact should at least be proportional to the actual memory usage). We do that adding and subtracting the SDS length when pushing / popping from the client->reply list. However it is quite simple to add bugs in such a setup, by not taking the objects in the list and the count in sync. For such reason, Redis has an assertion to track counts near 2^64: those are always the result of the counter wrapping around because we subtract more than we add. This commit adds the symmetrical assertion: when the list is empty since we sent everything, the reply_bytes count should be zero. Thanks to the new assertion it should be simple to also detect the other problem, where the count slowly increases because of over-counting. The assertion adds a conditional in the code that sends the buffer to the socket but should not create any measurable performance slowdown, listLength() just accesses a structure field, and this code path is totally dominated by write(2). Related to #4100.
-rw-r--r--src/networking.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/networking.c b/src/networking.c
index ec591245e..27006514d 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -927,6 +927,10 @@ int writeToClient(int fd, client *c, int handler_installed) {
listDelNode(c->reply,listFirst(c->reply));
c->sentlen = 0;
c->reply_bytes -= objlen;
+ /* If there are no longer objects in the list, we expect
+ * the count of reply bytes to be exactly zero. */
+ if (listLength(c->reply) == 0)
+ serverAssert(c->reply_bytes == 0);
}
}
/* Note that we avoid to send more than NET_MAX_WRITES_PER_EVENT