memarea.c revision 4c7d704408fc77467143a945dc2d0a856f72e674
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen#include "lib.h"
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen#include "memarea.h"
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenstruct memarea {
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen const void *data;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen size_t size;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen memarea_free_callback_t *callback;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen void *context;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen int refcount;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen};
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenstatic struct memarea memarea_empty = {
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen .refcount = 1,
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen};
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen#undef memarea_init
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenstruct memarea *
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenmemarea_init(const void *data, size_t size,
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen memarea_free_callback_t *callback, void *context)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen struct memarea *area;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_assert(callback != NULL);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen area = i_new(struct memarea, 1);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen area->data = data;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen area->size = size;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen area->callback = callback;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen area->context = context;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen area->refcount = 1;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen return area;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenstruct memarea *memarea_init_empty(void)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_assert(memarea_empty.refcount > 0);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen memarea_empty.refcount++;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen return &memarea_empty;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenvoid memarea_ref(struct memarea *area)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_assert(area->refcount > 0);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen area->refcount++;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenvoid memarea_unref(struct memarea **_area)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen struct memarea *area = *_area;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen *_area = NULL;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_assert(area->refcount > 0);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen if (--area->refcount > 0)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen return;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_assert(area != &memarea_empty);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen area->callback(area->context);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_free(area);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenvoid memarea_free_without_callback(struct memarea **_area)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen struct memarea *area = *_area;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen *_area = NULL;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_assert(memarea_get_refcount(area) == 1);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_free(area);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenunsigned int memarea_get_refcount(struct memarea *area)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen i_assert(area->refcount > 0);
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen return area->refcount;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenconst void *memarea_get(struct memarea *area, size_t *size_r)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen *size_r = area->size;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen return area->data;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainensize_t memarea_get_size(struct memarea *area)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen return area->size;
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainenvoid memarea_free_callback_noop(void *context ATTR_UNUSED)
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen{
4c7d704408fc77467143a945dc2d0a856f72e674Timo Sirainen}