/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>

#include "apr_buckets.h"
#include "apr_allocator.h"
#include "apr_support.h"

#define ALLOC_AMT (8192 - APR_MEMNODE_T_SIZE)

typedef struct node_header_t {
    apr_size_t size;
    apr_bucket_alloc_t *alloc;
    apr_memnode_t *memnode;
    struct node_header_t *next;
} node_header_t;

#define SIZEOF_NODE_HEADER_T  APR_ALIGN_DEFAULT(sizeof(node_header_t))
#define SMALL_NODE_SIZE       (APR_BUCKET_ALLOC_SIZE + SIZEOF_NODE_HEADER_T)

/** A list of free memory from which new buckets or private bucket
 *  structures can be allocated.
 */
struct apr_bucket_alloc_t {
    apr_pool_t *pool;
    apr_allocator_t *allocator;
    node_header_t *freelist;
    apr_memnode_t *blocks;
};

static apr_status_t alloc_cleanup(void *data)
{
    apr_bucket_alloc_t *list = data;
#if APR_POOL_DEBUG
    apr_allocator_t *allocator = NULL;
#endif

#if APR_POOL_DEBUG
    if (list->pool && list->allocator != apr_pool_allocator_get(list->pool)) {
        allocator = list->allocator;
    }
#endif

    apr_allocator_free(list->allocator, list->blocks);

#if APR_POOL_DEBUG
    if (allocator) {
        apr_allocator_destroy(allocator);
    }
#endif

    return APR_SUCCESS;
}

APR_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create(apr_pool_t *p)
{
    apr_allocator_t *allocator = apr_pool_allocator_get(p);
    apr_bucket_alloc_t *list;

#if APR_POOL_DEBUG
    /* may be NULL for debug mode. */
    if (allocator == NULL) {
        if (apr_allocator_create(&allocator) != APR_SUCCESS) {
            apr_abortfunc_t fn = apr_pool_abort_get(p);
            if (fn)
                (fn)(APR_ENOMEM);
            abort();
        }
    }
#endif
    list = apr_bucket_alloc_create_ex(allocator);
    if (list == NULL) {
            apr_abortfunc_t fn = apr_pool_abort_get(p);
            if (fn)
                (fn)(APR_ENOMEM);
            abort();
    }
    list->pool = p;
    apr_pool_cleanup_register(list->pool, list, alloc_cleanup,
                              apr_pool_cleanup_null);

    return list;
}

APR_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create_ex(
                                             apr_allocator_t *allocator)
{
    apr_bucket_alloc_t *list;
    apr_memnode_t *block;

    block = apr_allocator_alloc(allocator, ALLOC_AMT);
    if (!block) {
        return NULL;
    }
    list = (apr_bucket_alloc_t *)block->first_avail;
    list->pool = NULL;
    list->allocator = allocator;
    list->freelist = NULL;
    list->blocks = block;
    block->first_avail += APR_ALIGN_DEFAULT(sizeof(*list));
    APR_VALGRIND_NOACCESS(block->first_avail,
                          block->endp - block->first_avail);
    return list;
}

APR_DECLARE_NONSTD(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list)
{
    if (list->pool) {
        apr_pool_cleanup_kill(list->pool, list, alloc_cleanup);
    }

    apr_allocator_free(list->allocator, list->blocks);

#if APR_POOL_DEBUG
    if (list->pool && list->allocator != apr_pool_allocator_get(list->pool)) {
        apr_allocator_destroy(list->allocator);
    }
#endif
}

APR_DECLARE_NONSTD(apr_size_t) apr_bucket_alloc_aligned_floor(apr_bucket_alloc_t *list,
                                                              apr_size_t size)
{
    if (size <= SMALL_NODE_SIZE) {
        size = SMALL_NODE_SIZE;
    }
    else {
        if (size < APR_MEMNODE_T_SIZE) {
            size = apr_allocator_align(list->allocator, 0);
        }
        else {
            size = apr_allocator_align(list->allocator,
                                       size - APR_MEMNODE_T_SIZE);
        }
        size -= APR_MEMNODE_T_SIZE;
    }
    size -= SIZEOF_NODE_HEADER_T;
    return size;
}

APR_DECLARE_NONSTD(void *) apr_bucket_alloc(apr_size_t in_size,
                                            apr_bucket_alloc_t *list)
{
    node_header_t *node;
    apr_memnode_t *active = list->blocks;
    char *endp;
    apr_size_t size;

    size = in_size + SIZEOF_NODE_HEADER_T;
    if (size <= SMALL_NODE_SIZE) {
        if (list->freelist) {
            node = list->freelist;
            list->freelist = node->next;
            APR_VALGRIND_UNDEFINED((char *)node + SIZEOF_NODE_HEADER_T,
                                   SMALL_NODE_SIZE - SIZEOF_NODE_HEADER_T);
        }
        else {
            endp = active->first_avail + SMALL_NODE_SIZE;
            if (endp >= active->endp) {
                list->blocks = apr_allocator_alloc(list->allocator, ALLOC_AMT);
                if (!list->blocks) {
                    list->blocks = active;
                    return NULL;
                }
                list->blocks->next = active;
                active = list->blocks;
                endp = active->first_avail + SMALL_NODE_SIZE;
                APR_VALGRIND_NOACCESS(active->first_avail,
                                      active->endp - active->first_avail);
            }
            node = (node_header_t *)active->first_avail;
            APR_VALGRIND_UNDEFINED(node, SMALL_NODE_SIZE);
            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);
        if (!memnode) {
            return NULL;
        }
        node = (node_header_t *)memnode->first_avail;
        node->alloc = list;
        node->memnode = memnode;
        node->size = size;
    }
    return ((char *)node) + SIZEOF_NODE_HEADER_T;
}

#ifdef APR_BUCKET_DEBUG
#if APR_HAVE_STDLIB_H
#include <stdlib.h>
#endif
static void check_not_already_free(node_header_t *node)
{
    apr_bucket_alloc_t *list = node->alloc;
    node_header_t *curr = list->freelist;

    while (curr) {
        if (node == curr) {
            abort();
        }
        curr = curr->next;
    }
}
#else
#define check_not_already_free(node)
#endif

APR_DECLARE_NONSTD(void) apr_bucket_free(void *mem)
{
    node_header_t *node = (node_header_t *)((char *)mem - SIZEOF_NODE_HEADER_T);
    apr_bucket_alloc_t *list = node->alloc;

    if (node->size == SMALL_NODE_SIZE) {
        check_not_already_free(node);
        node->next = list->freelist;
        list->freelist = node;
        APR_VALGRIND_NOACCESS(mem, SMALL_NODE_SIZE - SIZEOF_NODE_HEADER_T);
    }
    else {
        apr_allocator_free(list->allocator, node->memnode);
    }
}
