[MEDIUM] report error on buffer writes larger than buffer size
Since it's now possible to change the buffer size by configuration,
we have to take special measures against writes that are larger than
the buffer size. Before this patch, the writers would indefinitely
block, waiting for some space to free up.
With this patch, the functions simply reject the data with an
appropriate code so that the writers can either detect and process
the error or go on, but never remain blocked.
This has been tested on the stats page which does no longer hang
with buffer sizes smaller than 2.5 kB (256 bytes is even OK for
the CSV version).
diff --git a/src/buffers.c b/src/buffers.c
index a20f3f4..ed2aa1e 100644
--- a/src/buffers.c
+++ b/src/buffers.c
@@ -31,9 +31,9 @@
/* writes <len> bytes from message <msg> to buffer <buf>. Returns -1 in case of
- * success, or the number of bytes available otherwise. The send limit is
- * automatically adjusted with the amount of data written.
- * FIXME-20060521: handle unaligned data.
+ * success, -2 if the message is larger than the buffer size, or the number of
+ * bytes available otherwise. The send limit is automatically adjusted with the
+ * amount of data written. FIXME-20060521: handle unaligned data.
*/
int buffer_write(struct buffer *buf, const char *msg, int len)
{
@@ -41,6 +41,15 @@
max = buffer_realign(buf);
+ if (len > buf->size) {
+ /* we can't write this chunk and will never be able to, because
+ * it is larger than the buffer. This must be reported as an
+ * error. Then we return -2 so that writers that don't care can
+ * ignore it and go on, and others can check for this value.
+ */
+ return -2;
+ }
+
if (len > max)
return max;
@@ -61,10 +70,11 @@
return -1;
}
-/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of
- * success, or the number of bytes available otherwise. If the chunk
- * has been written, its size is automatically reset to zero. The send limit is
- * automatically adjusted with the amount of data written.
+/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of success,
+ * -2 if it is larger than the buffer size, or the number of bytes available
+ * otherwise. If the chunk has been written, its size is automatically reset
+ * to zero. The send limit is automatically adjusted with the amount of data
+ * written.
*/
int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
{
@@ -73,6 +83,15 @@
if (chunk->len == 0)
return -1;
+ if (chunk->len > buf->size) {
+ /* we can't write this chunk and will never be able to, because
+ * it is larger than the buffer. This must be reported as an
+ * error. Then we return -2 so that writers that don't care can
+ * ignore it and go on, and others can check for this value.
+ */
+ return -2;
+ }
+
max = buffer_realign(buf);
if (chunk->len > max)