haproxy/src
Willy Tarreau 0abebcc0fb [MEDIUM] i/o: rework ->to_forward and ->send_max
The way the buffers and stream interfaces handled ->to_forward was
really not handy for multiple reasons. Now we've moved its control
to the receive-side of the buffer, which is also responsible for
keeping send_max up to date. This makes more sense as it now becomes
possible to send some pre-formatted data followed by forwarded data.

The following explanation has also been added to buffer.h to clarify
the situation. Right now, tests show that the I/O is behaving extremely
well. Some work will have to be done to adapt existing splice code
though.

/* Note about the buffer structure

   The buffer contains two length indicators, one to_forward counter and one
   send_max limit. First, it must be understood that the buffer is in fact
   split in two parts :
     - the visible data (->data, for ->l bytes)
     - the invisible data, typically in kernel buffers forwarded directly from
       the source stream sock to the destination stream sock (->splice_len
       bytes). Those are used only during forward.

   In order not to mix data streams, the producer may only feed the invisible
   data with data to forward, and only when the visible buffer is empty. The
   consumer may not always be able to feed the invisible buffer due to platform
   limitations (lack of kernel support).

   Conversely, the consumer must always take data from the invisible data first
   before ever considering visible data. There is no limit to the size of data
   to consume from the invisible buffer, as platform-specific implementations
   will rarely leave enough control on this. So any byte fed into the invisible
   buffer is expected to reach the destination file descriptor, by any means.
   However, it's the consumer's responsibility to ensure that the invisible
   data has been entirely consumed before consuming visible data. This must be
   reflected by ->splice_len. This is very important as this and only this can
   ensure strict ordering of data between buffers.

   The producer is responsible for decreasing ->to_forward and increasing
   ->send_max. The ->to_forward parameter indicates how many bytes may be fed
   into either data buffer without waking the parent up. The ->send_max
   parameter says how many bytes may be read from the visible buffer. Thus it
   may never exceed ->l. This parameter is updated by any buffer_write() as
   well as any data forwarded through the visible buffer.

   The consumer is responsible for decreasing ->send_max when it sends data
   from the visible buffer, and ->splice_len when it sends data from the
   invisible buffer.

   A real-world example consists in part in an HTTP response waiting in a
   buffer to be forwarded. We know the header length (300) and the amount of
   data to forward (content-length=9000). The buffer already contains 1000
   bytes of data after the 300 bytes of headers. Thus the caller will set
   ->send_max to 300 indicating that it explicitly wants to send those data,
   and set ->to_forward to 9000 (content-length). This value must be normalised
   immediately after updating ->to_forward : since there are already 1300 bytes
   in the buffer, 300 of which are already counted in ->send_max, and that size
   is smaller than ->to_forward, we must update ->send_max to 1300 to flush the
   whole buffer, and reduce ->to_forward to 8000. After that, the producer may
   try to feed the additional data through the invisible buffer using a
   platform-specific method such as splice().
 */
2009-01-09 10:15:03 +01:00
..
acl.c [MEDIUM] acl: when possible, report the name and requirements of ACLs in warnings 2008-08-03 09:41:05 +02:00
appsession.c [MEDIUM] memory: update pool_free2() to support NULL pointers 2008-08-03 20:48:50 +02:00
backend.c [BUG] "option transparent" is for backend, not frontend ! 2008-12-23 23:13:55 +01:00
base64.c [BUILD] change declaration of base64tab to fix build with Intel C++ 2008-06-29 17:17:38 +02:00
buffers.c [MEDIUM] add a send limit to a buffer 2008-12-28 10:58:52 +01:00
cfgparse.c [BUG] "option transparent" is for backend, not frontend ! 2008-12-23 23:13:55 +01:00
checks.c [BUG] check timeout must not be changed if timeout.check is not set 2008-12-23 09:58:49 +01:00
client.c [MEDIUM] enable inter-stream_interface wakeup calls 2008-12-28 11:09:02 +01:00
cttproxy.c [CLEANUP] remove many #include <types/xxx> from C files 2008-07-16 10:30:42 +02:00
dumpstats.c [MINOR] stats: indicate if a task is running in "show sess" 2008-12-08 00:16:21 +01:00
eb32tree.c [MINOR] merge ebtree version 3.0 2007-11-28 14:20:44 +01:00
eb64tree.c [MINOR] merge ebtree version 3.0 2007-11-28 14:20:44 +01:00
ebpttree.c [MINOR] merge ebtree version 3.0 2007-11-28 14:20:44 +01:00
ebtree.c [MINOR] merge ebtree version 3.0 2007-11-28 14:20:44 +01:00
ev_epoll.c [CLEANUP] remove 65 useless NULL checks before free 2008-08-03 20:48:50 +02:00
ev_kqueue.c [CLEANUP] remove 65 useless NULL checks before free 2008-08-03 20:48:50 +02:00
ev_poll.c [CLEANUP] remove 65 useless NULL checks before free 2008-08-03 20:48:50 +02:00
ev_select.c [CLEANUP] remove 65 useless NULL checks before free 2008-08-03 20:48:50 +02:00
ev_sepoll.c [OPTIM] ev_sepoll: detect newly created FDs and check them once 2008-11-02 10:19:07 +01:00
fd.c [CLEANUP] remove many #include <types/xxx> from C files 2008-07-16 10:30:42 +02:00
haproxy.c [BUG] critical errors should be reported even in daemon mode 2008-12-07 23:37:28 +01:00
hdr_idx.c [CLEANUP] remove many #include <types/xxx> from C files 2008-07-16 10:30:42 +02:00
log.c [CLEANUP] remove many #include <types/xxx> from C files 2008-07-16 10:30:42 +02:00
memory.c [MEDIUM] Fix memory freeing at exit 2008-05-30 07:07:19 +02:00
proto_http.c [MINOR] redirect: in prefix mode a "/" means not to change the URI 2008-12-07 23:48:39 +01:00
proto_tcp.c [MINOR] move the listener reference from fd to session 2008-12-07 16:45:10 +01:00
proto_uxst.c [MEDIUM] i/o: rework ->to_forward and ->send_max 2009-01-09 10:15:03 +01:00
protocols.c [CLEANUP] remove many #include <types/xxx> from C files 2008-07-16 10:30:42 +02:00
proxy.c [BUG] ensure that listeners from disabled proxies are correctly unbound. 2008-12-07 23:33:25 +01:00
queue.c [BUG] do not dequeue the backend's pending connections on a dead server 2008-12-07 23:51:12 +01:00
rbtree.c [MINOR] imported the rbtree function from Linux kernel 2007-01-07 02:12:57 +01:00
regex.c [CLEANUP] shut warnings 'is*' macros from ctype.h on solaris 2007-06-17 21:51:38 +02:00
server.c [CLEANUP] remove many #include <types/xxx> from C files 2008-07-16 10:30:42 +02:00
session.c [MEDIUM] i/o: rework ->to_forward and ->send_max 2009-01-09 10:15:03 +01:00
sessionhash.c [PATCH] appsessions: cleanup DEBUG_HASH and initialize request_counter 2008-08-13 23:43:26 +02:00
standard.c [MINOR] Allow to specify a domain for a cookie 2008-05-25 10:09:02 +02:00
stream_interface.c [MINOR] replace client_retnclose() with stream_int_retnclose() 2008-11-30 19:48:07 +01:00
stream_sock.c [MEDIUM] i/o: rework ->to_forward and ->send_max 2009-01-09 10:15:03 +01:00
task.c [MEDIUM] indicate a reason for a task wakeup 2008-11-02 10:19:08 +01:00
time.c [MINOR] introduce now_ms, the current date in milliseconds 2008-06-29 13:47:25 +02:00
uri_auth.c [CLEANUP] remove 65 useless NULL checks before free 2008-08-03 20:48:50 +02:00