memarea.c revision bcb4e51a409d94ae670de96afb8483a4f7855294
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch/* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "lib.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "memarea.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstruct memarea {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch const void *data;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch size_t size;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch memarea_free_callback_t *callback;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch void *context;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int refcount;
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic struct memarea memarea_empty = {
0b5bdb5ba6c8cb928b6d2dcc4636148bfa1a7ec7Stephan Bosch .refcount = 1,
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen};
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen#undef memarea_init
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Boschstruct memarea *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschmemarea_init(const void *data, size_t size,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch memarea_free_callback_t *callback, void *context)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct memarea *area;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_assert(callback != NULL);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch area = i_new(struct memarea, 1);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch area->data = data;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch area->size = size;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch area->callback = callback;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch area->context = context;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch area->refcount = 1;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch return area;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Boschstruct memarea *memarea_init_empty(void)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_assert(memarea_empty.refcount > 0);
0b5bdb5ba6c8cb928b6d2dcc4636148bfa1a7ec7Stephan Bosch memarea_empty.refcount++;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen return &memarea_empty;
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Bosch}
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
1920ef85b63738a06914e56508049dd0afe38732Timo Sirainenvoid memarea_ref(struct memarea *area)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch i_assert(area->refcount > 0);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch area->refcount++;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid memarea_unref(struct memarea **_area)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct memarea *area = *_area;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch *_area = NULL;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch i_assert(area->refcount > 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (--area->refcount > 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return;
0b5bdb5ba6c8cb928b6d2dcc4636148bfa1a7ec7Stephan Bosch i_assert(area != &memarea_empty);
10962368c30afde135743fd9796122e88a708e87Stephan Bosch area->callback(area->context);
10962368c30afde135743fd9796122e88a708e87Stephan Bosch i_free(area);
49beae176b0fadb122c776bbdfa0ea789c30f47fTimo Sirainen}
49beae176b0fadb122c776bbdfa0ea789c30f47fTimo Sirainen
d5cdf90f01fe1b5a5e049f341398b2ee329b4de5Stephan Boschvoid memarea_free_without_callback(struct memarea **_area)
7e59e4fdc89e55399fa60b3f6d866e7029c230feTimo Sirainen{
03142e79fbd4dd407b54348fe7aa16c11f577663Stephan Bosch struct memarea *area = *_area;
7e59e4fdc89e55399fa60b3f6d866e7029c230feTimo Sirainen
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch *_area = NULL;
49beae176b0fadb122c776bbdfa0ea789c30f47fTimo Sirainen i_assert(memarea_get_refcount(area) == 1);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_free(area);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschunsigned int memarea_get_refcount(struct memarea *area)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_assert(area->refcount > 0);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return area->refcount;
ec383c7840663a34033f5b1b027e7c530af564beTimo Sirainen}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
905fb741e6f9a40e7721bff095c52a87110b4de3Timo Sirainenconst void *memarea_get(struct memarea *area, size_t *size_r)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch *size_r = area->size;
34de49959c6612f519bff07ba5cd1f3ef964bb0cTimo Sirainen return area->data;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschsize_t memarea_get_size(struct memarea *area)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch{
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch return area->size;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
34de49959c6612f519bff07ba5cd1f3ef964bb0cTimo Sirainenvoid memarea_free_callback_noop(void *context ATTR_UNUSED)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch