1*6236dae4SAndroid Build Coastguard Worker<!-- 2*6236dae4SAndroid Build Coastguard WorkerCopyright (C) Daniel Stenberg, <[email protected]>, et al. 3*6236dae4SAndroid Build Coastguard Worker 4*6236dae4SAndroid Build Coastguard WorkerSPDX-License-Identifier: curl 5*6236dae4SAndroid Build Coastguard Worker--> 6*6236dae4SAndroid Build Coastguard Worker 7*6236dae4SAndroid Build Coastguard Worker# bufq 8*6236dae4SAndroid Build Coastguard Worker 9*6236dae4SAndroid Build Coastguard WorkerThis is an internal module for managing I/O buffers. A `bufq` can be written 10*6236dae4SAndroid Build Coastguard Workerto and read from. It manages read and write positions and has a maximum size. 11*6236dae4SAndroid Build Coastguard Worker 12*6236dae4SAndroid Build Coastguard Worker## read/write 13*6236dae4SAndroid Build Coastguard Worker 14*6236dae4SAndroid Build Coastguard WorkerIts basic read/write functions have a similar signature and return code handling 15*6236dae4SAndroid Build Coastguard Workeras many internal Curl read and write ones. 16*6236dae4SAndroid Build Coastguard Worker 17*6236dae4SAndroid Build Coastguard Worker 18*6236dae4SAndroid Build Coastguard Worker``` 19*6236dae4SAndroid Build Coastguard Workerssize_t Curl_bufq_write(struct bufq *q, const unsigned char *buf, size_t len, CURLcode *err); 20*6236dae4SAndroid Build Coastguard Worker 21*6236dae4SAndroid Build Coastguard Worker- returns the length written into `q` or -1 on error. 22*6236dae4SAndroid Build Coastguard Worker- writing to a full `q` returns -1 and set *err to CURLE_AGAIN 23*6236dae4SAndroid Build Coastguard Worker 24*6236dae4SAndroid Build Coastguard Workerssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len, CURLcode *err); 25*6236dae4SAndroid Build Coastguard Worker 26*6236dae4SAndroid Build Coastguard Worker- returns the length read from `q` or -1 on error. 27*6236dae4SAndroid Build Coastguard Worker- reading from an empty `q` returns -1 and set *err to CURLE_AGAIN 28*6236dae4SAndroid Build Coastguard Worker 29*6236dae4SAndroid Build Coastguard Worker``` 30*6236dae4SAndroid Build Coastguard Worker 31*6236dae4SAndroid Build Coastguard WorkerTo pass data into a `bufq` without an extra copy, read callbacks can be used. 32*6236dae4SAndroid Build Coastguard Worker 33*6236dae4SAndroid Build Coastguard Worker``` 34*6236dae4SAndroid Build Coastguard Workertypedef ssize_t Curl_bufq_reader(void *reader_ctx, unsigned char *buf, size_t len, 35*6236dae4SAndroid Build Coastguard Worker CURLcode *err); 36*6236dae4SAndroid Build Coastguard Worker 37*6236dae4SAndroid Build Coastguard Workerssize_t Curl_bufq_slurp(struct bufq *q, Curl_bufq_reader *reader, void *reader_ctx, 38*6236dae4SAndroid Build Coastguard Worker CURLcode *err); 39*6236dae4SAndroid Build Coastguard Worker``` 40*6236dae4SAndroid Build Coastguard Worker 41*6236dae4SAndroid Build Coastguard Worker`Curl_bufq_slurp()` invokes the given `reader` callback, passing it its own 42*6236dae4SAndroid Build Coastguard Workerinternal buffer memory to write to. It may invoke the `reader` several times, 43*6236dae4SAndroid Build Coastguard Workeras long as it has space and while the `reader` always returns the length that 44*6236dae4SAndroid Build Coastguard Workerwas requested. There are variations of `slurp` that call the `reader` at most 45*6236dae4SAndroid Build Coastguard Workeronce or only read in a maximum amount of bytes. 46*6236dae4SAndroid Build Coastguard Worker 47*6236dae4SAndroid Build Coastguard WorkerThe analog mechanism for write out buffer data is: 48*6236dae4SAndroid Build Coastguard Worker 49*6236dae4SAndroid Build Coastguard Worker``` 50*6236dae4SAndroid Build Coastguard Workertypedef ssize_t Curl_bufq_writer(void *writer_ctx, const unsigned char *buf, size_t len, 51*6236dae4SAndroid Build Coastguard Worker CURLcode *err); 52*6236dae4SAndroid Build Coastguard Worker 53*6236dae4SAndroid Build Coastguard Workerssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer, void *writer_ctx, 54*6236dae4SAndroid Build Coastguard Worker CURLcode *err); 55*6236dae4SAndroid Build Coastguard Worker``` 56*6236dae4SAndroid Build Coastguard Worker 57*6236dae4SAndroid Build Coastguard Worker`Curl_bufq_pass()` invokes the `writer`, passing its internal memory and 58*6236dae4SAndroid Build Coastguard Workerremove the amount that `writer` reports. 59*6236dae4SAndroid Build Coastguard Worker 60*6236dae4SAndroid Build Coastguard Worker## peek and skip 61*6236dae4SAndroid Build Coastguard Worker 62*6236dae4SAndroid Build Coastguard WorkerIt is possible to get access to the memory of data stored in a `bufq` with: 63*6236dae4SAndroid Build Coastguard Worker 64*6236dae4SAndroid Build Coastguard Worker``` 65*6236dae4SAndroid Build Coastguard Workerbool Curl_bufq_peek(const struct bufq *q, const unsigned char **pbuf, size_t *plen); 66*6236dae4SAndroid Build Coastguard Worker``` 67*6236dae4SAndroid Build Coastguard Worker 68*6236dae4SAndroid Build Coastguard WorkerOn returning TRUE, `pbuf` points to internal memory with `plen` bytes that one 69*6236dae4SAndroid Build Coastguard Workermay read. This is only valid until another operation on `bufq` is performed. 70*6236dae4SAndroid Build Coastguard Worker 71*6236dae4SAndroid Build Coastguard WorkerInstead of reading `bufq` data, one may simply skip it: 72*6236dae4SAndroid Build Coastguard Worker 73*6236dae4SAndroid Build Coastguard Worker``` 74*6236dae4SAndroid Build Coastguard Workervoid Curl_bufq_skip(struct bufq *q, size_t amount); 75*6236dae4SAndroid Build Coastguard Worker``` 76*6236dae4SAndroid Build Coastguard Worker 77*6236dae4SAndroid Build Coastguard WorkerThis removes `amount` number of bytes from the `bufq`. 78*6236dae4SAndroid Build Coastguard Worker 79*6236dae4SAndroid Build Coastguard Worker## unwrite 80*6236dae4SAndroid Build Coastguard Worker 81*6236dae4SAndroid Build Coastguard WorkerIt is possible to undo writes by calling: 82*6236dae4SAndroid Build Coastguard Worker 83*6236dae4SAndroid Build Coastguard Worker``` 84*6236dae4SAndroid Build Coastguard WorkerCURLcode Curl_bufq_unwrite(struct bufq *q, size_t len); 85*6236dae4SAndroid Build Coastguard Worker``` 86*6236dae4SAndroid Build Coastguard Worker 87*6236dae4SAndroid Build Coastguard WorkerThis will remove `len` bytes from the end of the bufq again. When removing 88*6236dae4SAndroid Build Coastguard Workermore bytes than are present, CURLE_AGAIN is returned and the bufq will be 89*6236dae4SAndroid Build Coastguard Workerempty. 90*6236dae4SAndroid Build Coastguard Worker 91*6236dae4SAndroid Build Coastguard Worker## lifetime 92*6236dae4SAndroid Build Coastguard Worker 93*6236dae4SAndroid Build Coastguard Worker`bufq` is initialized and freed similar to the `dynbuf` module. Code using 94*6236dae4SAndroid Build Coastguard Worker`bufq` holds a `struct bufq` somewhere. Before it uses it, it invokes: 95*6236dae4SAndroid Build Coastguard Worker 96*6236dae4SAndroid Build Coastguard Worker``` 97*6236dae4SAndroid Build Coastguard Workervoid Curl_bufq_init(struct bufq *q, size_t chunk_size, size_t max_chunks); 98*6236dae4SAndroid Build Coastguard Worker``` 99*6236dae4SAndroid Build Coastguard Worker 100*6236dae4SAndroid Build Coastguard WorkerThe `bufq` is told how many "chunks" of data it shall hold at maximum and how 101*6236dae4SAndroid Build Coastguard Workerlarge those "chunks" should be. There are some variants of this, allowing for 102*6236dae4SAndroid Build Coastguard Workermore options. How "chunks" are handled in a `bufq` is presented in the section 103*6236dae4SAndroid Build Coastguard Workerabout memory management. 104*6236dae4SAndroid Build Coastguard Worker 105*6236dae4SAndroid Build Coastguard WorkerThe user of the `bufq` has the responsibility to call: 106*6236dae4SAndroid Build Coastguard Worker 107*6236dae4SAndroid Build Coastguard Worker``` 108*6236dae4SAndroid Build Coastguard Workervoid Curl_bufq_free(struct bufq *q); 109*6236dae4SAndroid Build Coastguard Worker``` 110*6236dae4SAndroid Build Coastguard Workerto free all resources held by `q`. It is possible to reset a `bufq` to empty via: 111*6236dae4SAndroid Build Coastguard Worker 112*6236dae4SAndroid Build Coastguard Worker``` 113*6236dae4SAndroid Build Coastguard Workervoid Curl_bufq_reset(struct bufq *q); 114*6236dae4SAndroid Build Coastguard Worker``` 115*6236dae4SAndroid Build Coastguard Worker 116*6236dae4SAndroid Build Coastguard Worker## memory management 117*6236dae4SAndroid Build Coastguard Worker 118*6236dae4SAndroid Build Coastguard WorkerInternally, a `bufq` uses allocation of fixed size, e.g. the "chunk_size", up 119*6236dae4SAndroid Build Coastguard Workerto a maximum number, e.g. "max_chunks". These chunks are allocated on demand, 120*6236dae4SAndroid Build Coastguard Workertherefore writing to a `bufq` may return `CURLE_OUT_OF_MEMORY`. Once the max 121*6236dae4SAndroid Build Coastguard Workernumber of chunks are used, the `bufq` reports that it is "full". 122*6236dae4SAndroid Build Coastguard Worker 123*6236dae4SAndroid Build Coastguard WorkerEach chunks has a `read` and `write` index. A `bufq` keeps its chunks in a 124*6236dae4SAndroid Build Coastguard Workerlist. Reading happens always at the head chunk, writing always goes to the 125*6236dae4SAndroid Build Coastguard Workertail chunk. When the head chunk becomes empty, it is removed. When the tail 126*6236dae4SAndroid Build Coastguard Workerchunk becomes full, another chunk is added to the end of the list, becoming 127*6236dae4SAndroid Build Coastguard Workerthe new tail. 128*6236dae4SAndroid Build Coastguard Worker 129*6236dae4SAndroid Build Coastguard WorkerChunks that are no longer used are returned to a `spare` list by default. If 130*6236dae4SAndroid Build Coastguard Workerthe `bufq` is created with option `BUFQ_OPT_NO_SPARES` those chunks are freed 131*6236dae4SAndroid Build Coastguard Workerright away. 132*6236dae4SAndroid Build Coastguard Worker 133*6236dae4SAndroid Build Coastguard WorkerIf a `bufq` is created with a `bufc_pool`, the no longer used chunks are 134*6236dae4SAndroid Build Coastguard Workerreturned to the pool. Also `bufq` asks the pool for a chunk when it needs one. 135*6236dae4SAndroid Build Coastguard WorkerMore in section "pools". 136*6236dae4SAndroid Build Coastguard Worker 137*6236dae4SAndroid Build Coastguard Worker## empty, full and overflow 138*6236dae4SAndroid Build Coastguard Worker 139*6236dae4SAndroid Build Coastguard WorkerOne can ask about the state of a `bufq` with methods such as 140*6236dae4SAndroid Build Coastguard Worker`Curl_bufq_is_empty(q)`, `Curl_bufq_is_full(q)`, etc. The amount of data held 141*6236dae4SAndroid Build Coastguard Workerby a `bufq` is the sum of the data in all its chunks. This is what is reported 142*6236dae4SAndroid Build Coastguard Workerby `Curl_bufq_len(q)`. 143*6236dae4SAndroid Build Coastguard Worker 144*6236dae4SAndroid Build Coastguard WorkerNote that a `bufq` length and it being "full" are only loosely related. A 145*6236dae4SAndroid Build Coastguard Workersimple example: 146*6236dae4SAndroid Build Coastguard Worker 147*6236dae4SAndroid Build Coastguard Worker* create a `bufq` with chunk_size=1000 and max_chunks=4. 148*6236dae4SAndroid Build Coastguard Worker* write 4000 bytes to it, it reports "full" 149*6236dae4SAndroid Build Coastguard Worker* read 1 bytes from it, it still reports "full" 150*6236dae4SAndroid Build Coastguard Worker* read 999 more bytes from it, and it is no longer "full" 151*6236dae4SAndroid Build Coastguard Worker 152*6236dae4SAndroid Build Coastguard WorkerThe reason for this is that full really means: *bufq uses max_chunks and the 153*6236dae4SAndroid Build Coastguard Workerlast one cannot be written to*. 154*6236dae4SAndroid Build Coastguard Worker 155*6236dae4SAndroid Build Coastguard WorkerWhen you read 1 byte from the head chunk in the example above, the head still 156*6236dae4SAndroid Build Coastguard Workerhold 999 unread bytes. Only when those are also read, can the head chunk be 157*6236dae4SAndroid Build Coastguard Workerremoved and a new tail be added. 158*6236dae4SAndroid Build Coastguard Worker 159*6236dae4SAndroid Build Coastguard WorkerThere is another variation to this. If you initialized a `bufq` with option 160*6236dae4SAndroid Build Coastguard Worker`BUFQ_OPT_SOFT_LIMIT`, it allows writes **beyond** the `max_chunks`. It 161*6236dae4SAndroid Build Coastguard Workerreports **full**, but one can **still** write. This option is necessary, if 162*6236dae4SAndroid Build Coastguard Workerpartial writes need to be avoided. It means that you need other checks to keep 163*6236dae4SAndroid Build Coastguard Workerthe `bufq` from growing ever larger and larger. 164*6236dae4SAndroid Build Coastguard Worker 165*6236dae4SAndroid Build Coastguard Worker 166*6236dae4SAndroid Build Coastguard Worker## pools 167*6236dae4SAndroid Build Coastguard Worker 168*6236dae4SAndroid Build Coastguard WorkerA `struct bufc_pool` may be used to create chunks for a `bufq` and keep spare 169*6236dae4SAndroid Build Coastguard Workerones around. It is initialized and used via: 170*6236dae4SAndroid Build Coastguard Worker 171*6236dae4SAndroid Build Coastguard Worker``` 172*6236dae4SAndroid Build Coastguard Workervoid Curl_bufcp_init(struct bufc_pool *pool, size_t chunk_size, size_t spare_max); 173*6236dae4SAndroid Build Coastguard Worker 174*6236dae4SAndroid Build Coastguard Workervoid Curl_bufq_initp(struct bufq *q, struct bufc_pool *pool, size_t max_chunks, int opts); 175*6236dae4SAndroid Build Coastguard Worker``` 176*6236dae4SAndroid Build Coastguard Worker 177*6236dae4SAndroid Build Coastguard WorkerThe pool gets the size and the mount of spares to keep. The `bufq` gets the 178*6236dae4SAndroid Build Coastguard Workerpool and the `max_chunks`. It no longer needs to know the chunk sizes, as 179*6236dae4SAndroid Build Coastguard Workerthose are managed by the pool. 180*6236dae4SAndroid Build Coastguard Worker 181*6236dae4SAndroid Build Coastguard WorkerA pool can be shared between many `bufq`s, as long as all of them operate in 182*6236dae4SAndroid Build Coastguard Workerthe same thread. In curl that would be true for all transfers using the same 183*6236dae4SAndroid Build Coastguard Workermulti handle. The advantages of a pool are: 184*6236dae4SAndroid Build Coastguard Worker 185*6236dae4SAndroid Build Coastguard Worker* when all `bufq`s are empty, only memory for `max_spare` chunks in the pool 186*6236dae4SAndroid Build Coastguard Worker is used. Empty `bufq`s holds no memory. 187*6236dae4SAndroid Build Coastguard Worker* the latest spare chunk is the first to be handed out again, no matter which 188*6236dae4SAndroid Build Coastguard Worker `bufq` needs it. This keeps the footprint of "recently used" memory smaller. 189