■
bucketのheapに関する操作
- heap_bucket_read
static apr_status_t heap_bucket_read(apr_bucket *b, const char **str, apr_size_t *len, apr_read_type_e block) { apr_bucket_heap *h = b->data; *str = h->base + b->start; *len = b->length; return APR_SUCCESS; }
bucketからデータを*strに読み込む。
- heap_bucket\destroy
static void heap_bucket_destroy(void *data) { apr_bucket_heap *h = data; if (apr_bucket_shared_destroy(h)) { (*h->free_func)(h->base); apr_bucket_free(h); } } //apr_buckets_refcount.c APU_DECLARE(int) apr_bucket_shared_destroy(void *data) { apr_bucket_refcount *r = data; r->refcount--; return (r->refcount == 0); } || refcountが0(どこからも参照されていない)ならばデータをfreeする -apr_bucket_heap_make >|c| APU_DECLARE(apr_bucket *) apr_bucket_heap_make(apr_bucket *b, const char *buf, apr_size_t length, void (*free_func)(void *data)) || 1. apr_bucket_allocでメモリを確保する 2. free_funcがNULLならばデフォルトのfree処理(apr_bucket_free)をセットし新しいheap領域にデータbufをコピーする 3. free_funcが引数で渡されていればそれをセット 4. apr_bucket_shared_makeを呼び出す -apr_bucket_shared_make (apr_buckets_refcoount.c) >|c| APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data, apr_off_t start, apr_size_t length) { apr_bucket_refcount *r = data; b->data = r; b->start = start; b->length = length; /* caller initializes the type field */ r->refcount = 1; return b; }
共有bucketの作成
APU_DECLARE(apr_bucket *) apr_bucket_heap_create(const char *buf, apr_size_t length, void (*free_func)(void *data), apr_bucket_alloc_t *list)
1. apr_bucket_allocでメモリ確保
2. APR_BUCKET_INITの呼び出し
#define APR_BUCKET_INIT(e) APR_RING_ELEM_INIT((e), link)
#define APR_RING_ELEM_INIT(ep, link) do {
APR_RING_NEXT((ep), link) = (ep);
APR_RING_PREV((ep), link) = (ep);
} while (0)
APU_DECLARE_NONSTD(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t *list) { node_header_t *node; apr_memnode_t *active = list->blocks; char *endp; size += SIZEOF_NODE_HEADER_T; if (size <= SMALL_NODE_SIZE) { if (list->freelist) { node = list->freelist; list->freelist = node->next; } else { endp = active->first_avail + SMALL_NODE_SIZE; if (endp >= active->endp) { list->blocks = apr_allocator_alloc(list->allocator, ALLOC_AMT); list->blocks->next = active; active = list->blocks; endp = active->first_avail + SMALL_NODE_SIZE; } node = (node_header_t *)active->first_avail; node->alloc = list; node->memnode = active; node->size = SMALL_NODE_SIZE; active->first_avail = endp; } } else { apr_memnode_t *memnode = apr_allocator_alloc(list->allocator, size); node = (node_header_t *)memnode->first_avail; node->alloc = list; node->memnode = memnode; node->size = size; } return ((char *)node) + SIZEOF_NODE_HEADER_T; }
freeリストから空いているメモリ領域の位置を取得。
空きがなければfreeリストを拡張する。