mempool-alloconly.c revision 01a170c984df9e5fc0f28aa7695e0cbbdb3c9029
/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
/* @UNSAFE: whole file */
#include "lib.h"
#include "safe-memset.h"
#include "mempool.h"
#include <stdlib.h>
#ifdef HAVE_GC_GC_H
# include <gc.h>
#endif
#define MAX_ALLOC_SIZE SSIZE_T_MAX
struct alloconly_pool {
int refcount;
struct pool_block *block;
#ifdef DEBUG
const char *name;
bool disable_warning;
#endif
bool clean_frees;
};
struct pool_block {
struct pool_block *prev;
/* unsigned char data[]; */
};
#define POOL_BLOCK_DATA(block) \
((char *) (block) + SIZEOF_POOLBLOCK)
static const struct pool_vfuncs static_alloconly_pool_vfuncs = {
};
static const struct pool static_alloconly_pool = {
};
#ifdef DEBUG
{
size_t i;
if (data[i] != '\0')
i_unreached();
}
}
#endif
{
#ifdef DEBUG
#endif
/* create a fake alloconly_pool so we can call block_alloc() */
/* now allocate the actual alloconly_pool from the created block */
/* the pool allocation must be from the first block */
#ifdef DEBUG
}
/* set base_size so p_clear() doesn't trash alloconly_pool structure. */
#endif
}
{
struct alloconly_pool *apool;
return pool;
}
{
void *block;
/* destroy all but the last block */
/* destroy the last block */
#ifdef DEBUG
#else
if (apool->clean_frees)
#endif
#ifndef USE_GC
#endif
}
{
#ifdef DEBUG
#else
return "alloconly";
#endif
}
{
}
{
return;
/* erase the pointer before freeing anything, as the pointer may
exist inside the pool's memory area */
}
{
struct pool_block *block;
/* each block is at least twice the size of the previous one */
#ifdef DEBUG
if (!apool->disable_warning) {
}
#endif
}
#ifndef USE_GC
#else
#endif
}
{
void *mem;
/* we need a new block */
}
return mem;
}
{
/* we can free only the last allocation */
}
}
{
/* see if we want to grow the memory we allocated last */
/* yeah, see if we can grow */
/* just shrink the available size */
return TRUE;
}
}
return FALSE;
}
{
unsigned char *new_mem;
return mem;
/* see if we can directly grow it */
/* slow way - allocate + copy */
}
return mem;
}
{
struct pool_block *block;
#ifdef DEBUG
#endif
/* destroy all blocks but the oldest, which contains the
struct alloconly_pool allocation. */
#ifdef DEBUG
#else
if (apool->clean_frees)
#endif
#ifndef USE_GC
#endif
}
/* clear the first block */
#ifdef DEBUG
#else
#endif
}
{
}