|
Data Structures |
| struct | apr_bucket_type_t |
| struct | apr_bucket |
| struct | apr_bucket_brigade |
| struct | apr_bucket_refcount |
| struct | apr_bucket_heap |
| struct | apr_bucket_pool |
| struct | apr_bucket_mmap |
| struct | apr_bucket_file |
| union | apr_bucket_structs |
Defines |
| #define | APR_BUCKET_BUFF_SIZE 8000 |
| #define | APR_BRIGADE_CHECK_CONSISTENCY(b) |
| #define | APR_BUCKET_CHECK_CONSISTENCY(e) |
| #define | APR_BRIGADE_SENTINEL(b) APR_RING_SENTINEL(&(b)->list, apr_bucket, link) |
| #define | APR_BRIGADE_EMPTY(b) APR_RING_EMPTY(&(b)->list, apr_bucket, link) |
| #define | APR_BRIGADE_FIRST(b) APR_RING_FIRST(&(b)->list) |
| #define | APR_BRIGADE_LAST(b) APR_RING_LAST(&(b)->list) |
| #define | APR_BRIGADE_INSERT_HEAD(b, e) |
| #define | APR_BRIGADE_INSERT_TAIL(b, e) |
| #define | APR_BRIGADE_CONCAT(a, b) |
| #define | APR_BRIGADE_PREPEND(a, b) |
| #define | APR_BUCKET_INSERT_BEFORE(a, b) |
| #define | APR_BUCKET_INSERT_AFTER(a, b) |
| #define | APR_BUCKET_NEXT(e) APR_RING_NEXT((e), link) |
| #define | APR_BUCKET_PREV(e) APR_RING_PREV((e), link) |
| #define | APR_BUCKET_REMOVE(e) APR_RING_REMOVE((e), link) |
| #define | APR_BUCKET_INIT(e) APR_RING_ELEM_INIT((e), link) |
| #define | APR_BUCKET_IS_METADATA(e) ((e)->type->is_metadata) |
| #define | APR_BUCKET_IS_FLUSH(e) ((e)->type == &apr_bucket_type_flush) |
| #define | APR_BUCKET_IS_EOS(e) ((e)->type == &apr_bucket_type_eos) |
| #define | APR_BUCKET_IS_FILE(e) ((e)->type == &apr_bucket_type_file) |
| #define | APR_BUCKET_IS_PIPE(e) ((e)->type == &apr_bucket_type_pipe) |
| #define | APR_BUCKET_IS_SOCKET(e) ((e)->type == &apr_bucket_type_socket) |
| #define | APR_BUCKET_IS_HEAP(e) ((e)->type == &apr_bucket_type_heap) |
| #define | APR_BUCKET_IS_TRANSIENT(e) ((e)->type == &apr_bucket_type_transient) |
| #define | APR_BUCKET_IS_IMMORTAL(e) ((e)->type == &apr_bucket_type_immortal) |
| #define | APR_BUCKET_IS_MMAP(e) ((e)->type == &apr_bucket_type_mmap) |
| #define | APR_BUCKET_IS_POOL(e) ((e)->type == &apr_bucket_type_pool) |
| #define | APR_BUCKET_ALLOC_SIZE APR_ALIGN_DEFAULT(2*sizeof(apr_bucket_structs)) |
| #define | apr_bucket_destroy(e) |
| #define | apr_bucket_delete(e) |
| #define | apr_bucket_read(e, str, len, block) (e)->type->read(e, str, len, block) |
| #define | apr_bucket_setaside(e, p) (e)->type->setaside(e,p) |
| #define | apr_bucket_split(e, point) (e)->type->split(e, point) |
| #define | apr_bucket_copy(e, c) (e)->type->copy(e, c) |
Typedefs |
| typedef struct apr_bucket_brigade | apr_bucket_brigade |
| typedef struct apr_bucket | apr_bucket |
| typedef struct apr_bucket_alloc_t | apr_bucket_alloc_t |
| typedef struct apr_bucket_type_t | apr_bucket_type_t |
| typedef apr_status_t(* | apr_brigade_flush )(apr_bucket_brigade *bb, void *ctx) |
| typedef struct apr_bucket_refcount | apr_bucket_refcount |
| typedef struct apr_bucket_heap | apr_bucket_heap |
| typedef struct apr_bucket_pool | apr_bucket_pool |
| typedef struct apr_bucket_mmap | apr_bucket_mmap |
| typedef struct apr_bucket_file | apr_bucket_file |
| typedef union apr_bucket_structs | apr_bucket_structs |
Enumerations |
| enum | apr_read_type_e { APR_BLOCK_READ,
APR_NONBLOCK_READ
} |
Functions |
| apr_bucket_brigade * | apr_brigade_create (apr_pool_t *p, apr_bucket_alloc_t *list) |
| apr_status_t | apr_brigade_destroy (apr_bucket_brigade *b) |
| apr_status_t | apr_brigade_cleanup (void *data) |
| apr_bucket_brigade * | apr_brigade_split_ex (apr_bucket_brigade *b, apr_bucket *e, apr_bucket_brigade *a) |
| apr_bucket_brigade * | apr_brigade_split (apr_bucket_brigade *b, apr_bucket *e) |
| apr_status_t | apr_brigade_partition (apr_bucket_brigade *b, apr_off_t point, apr_bucket **after_point) |
| apr_status_t | apr_brigade_length (apr_bucket_brigade *bb, int read_all, apr_off_t *length) |
| apr_status_t | apr_brigade_flatten (apr_bucket_brigade *bb, char *c, apr_size_t *len) |
| apr_status_t | apr_brigade_pflatten (apr_bucket_brigade *bb, char **c, apr_size_t *len, apr_pool_t *pool) |
| apr_status_t | apr_brigade_split_line (apr_bucket_brigade *bbOut, apr_bucket_brigade *bbIn, apr_read_type_e block, apr_off_t maxbytes) |
| apr_status_t | apr_brigade_to_iovec (apr_bucket_brigade *b, struct iovec *vec, int *nvec) |
| apr_status_t | apr_brigade_vputstrs (apr_bucket_brigade *b, apr_brigade_flush flush, void *ctx, va_list va) |
| apr_status_t | apr_brigade_write (apr_bucket_brigade *b, apr_brigade_flush flush, void *ctx, const char *str, apr_size_t nbyte) |
| apr_status_t | apr_brigade_writev (apr_bucket_brigade *b, apr_brigade_flush flush, void *ctx, const struct iovec *vec, apr_size_t nvec) |
| apr_status_t | apr_brigade_puts (apr_bucket_brigade *bb, apr_brigade_flush flush, void *ctx, const char *str) |
| apr_status_t | apr_brigade_putc (apr_bucket_brigade *b, apr_brigade_flush flush, void *ctx, const char c) |
| apr_status_t | apr_brigade_putstrs (apr_bucket_brigade *b, apr_brigade_flush flush, void *ctx,...) |
| apr_status_t | apr_brigade_printf (apr_bucket_brigade *b, apr_brigade_flush flush, void *ctx, const char *fmt,...) |
| apr_status_t | apr_brigade_vprintf (apr_bucket_brigade *b, apr_brigade_flush flush, void *ctx, const char *fmt, va_list va) |
| apr_bucket * | apr_brigade_insert_file (apr_bucket_brigade *bb, apr_file_t *f, apr_off_t start, apr_off_t len, apr_pool_t *p) |
| apr_bucket_alloc_t * | apr_bucket_alloc_create (apr_pool_t *p) |
| apr_bucket_alloc_t * | apr_bucket_alloc_create_ex (apr_allocator_t *allocator) |
| void | apr_bucket_alloc_destroy (apr_bucket_alloc_t *list) |
| void * | apr_bucket_alloc (apr_size_t size, apr_bucket_alloc_t *list) |
| void | apr_bucket_free (void *block) |
| apr_status_t | apr_bucket_setaside_noop (apr_bucket *data, apr_pool_t *pool) |
| apr_status_t | apr_bucket_setaside_notimpl (apr_bucket *data, apr_pool_t *pool) |
| apr_status_t | apr_bucket_split_notimpl (apr_bucket *data, apr_size_t point) |
| apr_status_t | apr_bucket_copy_notimpl (apr_bucket *e, apr_bucket **c) |
| void | apr_bucket_destroy_noop (void *data) |
| apr_status_t | apr_bucket_simple_split (apr_bucket *b, apr_size_t point) |
| apr_status_t | apr_bucket_simple_copy (apr_bucket *a, apr_bucket **b) |
| apr_bucket * | apr_bucket_shared_make (apr_bucket *b, void *data, apr_off_t start, apr_size_t length) |
| int | apr_bucket_shared_destroy (void *data) |
| apr_status_t | apr_bucket_shared_split (apr_bucket *b, apr_size_t point) |
| apr_status_t | apr_bucket_shared_copy (apr_bucket *a, apr_bucket **b) |
| apr_bucket * | apr_bucket_eos_create (apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_eos_make (apr_bucket *b) |
| apr_bucket * | apr_bucket_flush_create (apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_flush_make (apr_bucket *b) |
| apr_bucket * | apr_bucket_immortal_create (const char *buf, apr_size_t nbyte, apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_immortal_make (apr_bucket *b, const char *buf, apr_size_t nbyte) |
| apr_bucket * | apr_bucket_transient_create (const char *buf, apr_size_t nbyte, apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_transient_make (apr_bucket *b, const char *buf, apr_size_t nbyte) |
| apr_bucket * | apr_bucket_heap_create (const char *buf, apr_size_t nbyte, void(*free_func)(void *data), apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_heap_make (apr_bucket *b, const char *buf, apr_size_t nbyte, void(*free_func)(void *data)) |
| apr_bucket * | apr_bucket_pool_create (const char *buf, apr_size_t length, apr_pool_t *pool, apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_pool_make (apr_bucket *b, const char *buf, apr_size_t length, apr_pool_t *pool) |
| apr_bucket * | apr_bucket_mmap_create (apr_mmap_t *mm, apr_off_t start, apr_size_t length, apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_mmap_make (apr_bucket *b, apr_mmap_t *mm, apr_off_t start, apr_size_t length) |
| apr_bucket * | apr_bucket_socket_create (apr_socket_t *thissock, apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_socket_make (apr_bucket *b, apr_socket_t *thissock) |
| apr_bucket * | apr_bucket_pipe_create (apr_file_t *thispipe, apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_pipe_make (apr_bucket *b, apr_file_t *thispipe) |
| apr_bucket * | apr_bucket_file_create (apr_file_t *fd, apr_off_t offset, apr_size_t len, apr_pool_t *p, apr_bucket_alloc_t *list) |
| apr_bucket * | apr_bucket_file_make (apr_bucket *b, apr_file_t *fd, apr_off_t offset, apr_size_t len, apr_pool_t *p) |
| apr_status_t | apr_bucket_file_enable_mmap (apr_bucket *b, int enabled) |
Variables |
| const apr_bucket_type_t | apr_bucket_type_flush |
| const apr_bucket_type_t | apr_bucket_type_eos |
| const apr_bucket_type_t | apr_bucket_type_file |
| const apr_bucket_type_t | apr_bucket_type_heap |
| const apr_bucket_type_t | apr_bucket_type_mmap |
| const apr_bucket_type_t | apr_bucket_type_pool |
| const apr_bucket_type_t | apr_bucket_type_pipe |
| const apr_bucket_type_t | apr_bucket_type_immortal |
| const apr_bucket_type_t | apr_bucket_type_transient |
| const apr_bucket_type_t | apr_bucket_type_socket |
The one-sentence buzzword-laden overview: Bucket brigades represent a complex data stream that can be passed through a layered IO system without unnecessary copying. A longer overview follows...
A bucket brigade is a doubly linked list (ring) of buckets, so we aren't limited to inserting at the front and removing at the end. Buckets are only passed around as members of a brigade, although singleton buckets can occur for short periods of time.
Buckets are data stores of various types. They can refer to data in memory, or part of a file or mmap area, or the output of a process, etc. Buckets also have some type-dependent accessor functions: read, split, copy, setaside, and destroy.
read returns the address and size of the data in the bucket. If the data isn't in memory then it is read in and the bucket changes type so that it can refer to the new location of the data. If all the data doesn't fit in the bucket then a new bucket is inserted into the brigade to hold the rest of it.
split divides the data in a bucket into two regions. After a split the original bucket refers to the first part of the data and a new bucket inserted into the brigade after the original bucket refers to the second part of the data. Reference counts are maintained as necessary.
setaside ensures that the data in the bucket has a long enough lifetime. Sometimes it is convenient to create a bucket referring to data on the stack in the expectation that it will be consumed (output to the network) before the stack is unwound. If that expectation turns out not to be valid, the setaside function is called to move the data somewhere safer.
copy makes a duplicate of the bucket structure as long as it's possible to have multiple references to a single copy of the data itself. Not all bucket types can be copied.
destroy maintains the reference counts on the resources used by a bucket and frees them if necessary.
Note: all of the above functions have wrapper macros (apr_bucket_read(), apr_bucket_destroy(), etc), and those macros should be used rather than using the function pointers directly.
To write a bucket brigade, they are first made into an iovec, so that we don't write too little data at one time. Currently we ignore compacting the buckets into as few buckets as possible, but if we really want good performance, then we need to compact the buckets before we convert to an iovec, or possibly while we are converting to an iovec.
- See also:
- apr_bucket_brigade