blob: 564d868ca41e13f25ce68dfa7e1bc669958dadfe [file] [log] [blame]
Willy Tarreaua4827462014-10-30 16:07:16 +010012014/10/30 - dynamic buffer management
2
3Since HTTP/2 processing will significantly increase the need for buffering, it
4becomes mandatory to be able to support dynamic buffer allocation. This also
5means that at any moment some buffer allocation will fail and that a task or an
6I/O operation will have to be paused for the time needed to allocate a buffer.
7
8There are 3 places where buffers are needed :
9
10 - receive side of a stream interface. A connection notifies about a pending
11 recv() and the SI calls the receive function to put the data into a buffer.
12 Here the buffer will have to be picked from a pool first, and if the
13 allocation fails, the I/O will have to temporarily be disabled, the
14 connection will have to subscribe for buffer release notification to be
15 woken up once a buffer is available again. It's important to keep in mind
16 that buffer availability doesn't necessarily mean a desire to enable recv
17 again, just that recv is not paused anymore for resource reasons.
18
19 - receive side of a stream interface when the other end point is an applet.
20 The applet wants to write into the buffer and for this the buffer needs to
21 be allocated as well. It is the same as above except that it is the applet
22 which is put to a pause. Since the applet might be at the core of the task
23 itself, it could become tricky to handle the situation correctly. Stats and
24 peers are in this situation.
25
26 - Tx of a task : some tasks perform spontaneous writes to a buffer. Checks
27 are an example of this. The checks will have to be able to sleep while a
28 buffer is being awaited.
29
30One important point is that such pauses must not prevent the task from timing
31out. There it becomes difficult because in the case of a time out, we could
32want to emit a timeout error message and for this, require a buffer. So it is
33important to keep the ability not to send messages upon error processing, and
34to be able to give up and stop waiting for buffers.
35
36The refill mechanism needs to be designed in a thread-safe way because this
37will become one of the rare cases of inter-task activity. Thus it is important
38to ensure that checking the state of the task and passing of the freshly
39released buffer are performed atomically, and that in case the task doesn't
40want it anymore, it is responsible for passing it to the next one.
41