Commit b54540cb b54540cbbc95069b6d073246a575683170920275 by Sergey Poznyakoff

Improve opool API

* configure.ac: Version 2.99.993
* NEWS: Update.

* include/mailutils/opool.h (MU_OPOOL_DEFAULT)
(MU_OPOOL_ENOMEMABRT): New defines.
(mu_opool_create): Change meaning of the 2nd argument. All uses updated.
(mu_opool_free, mu_opool_dup): New proto.
* libmailutils/base/opool.c (_mu_opool) <memerr>: Replace with flags.
<head,tail,free>: Rename.
(mu_opool_free, mu_opool_dup): New functions.
(mu_opool_head): Bugfix.
1 parent c6848f52
GNU mailutils NEWS -- history of user-visible changes. 2016-10-28
GNU mailutils NEWS -- history of user-visible changes. 2016-10-30
Copyright (C) 2002-2016 Free Software Foundation, Inc.
See the end of file for copying conditions.
Please send mailutils bug reports to <bug-mailutils@gnu.org>.
Version 2.99.992 (Git)
Version 2.99.993 (Git)
This version is a major rewrite of GNU Mailutils. Quite a few parts
of the basic framework were rewritten from scratch, while some others
......
......@@ -144,7 +144,7 @@ expand_line (const char *str, mu_message_t msg)
if (!*str)
return NULL;
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
for (p = str; *p; p++)
{
switch (*p)
......
......@@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU General Public License along
dnl with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ(2.63)
AC_INIT([GNU Mailutils], [2.99.992], [bug-mailutils@gnu.org], [mailutils],
AC_INIT([GNU Mailutils], [2.99.993], [bug-mailutils@gnu.org], [mailutils],
[http://mailutils.org])
AC_CONFIG_SRCDIR([libmailutils/mailbox/mailbox.c])
AC_CONFIG_AUX_DIR([build-aux])
......
......@@ -24,10 +24,12 @@
# define MU_OPOOL_BUCKET_SIZE 1024
#endif
/* Create an object pool. If MEMERR is not 0, any operation of the
resulting pool (including mu_opool_create itself) will abort on
not enough memory condition, using mu_alloc_die. */
int mu_opool_create (mu_opool_t *pret, int memerr);
/* Flags for mu_opool_create call: */
#define MU_OPOOL_DEFAULT 0
#define MU_OPOOL_ENOMEMABRT 0x01 /* Abort on ENOMEM error */
/* Create an object pool. */
int mu_opool_create (mu_opool_t *pret, int flags);
int mu_opool_set_bucket_size (mu_opool_t opool, size_t size);
int mu_opool_get_bucket_size (mu_opool_t opool, size_t *psize);
......@@ -39,6 +41,10 @@ int mu_opool_union (mu_opool_t *dst, mu_opool_t *src);
begin a new object. */
void mu_opool_clear (mu_opool_t opool);
/* Free object OBJ from the pool. If OBJ is NULL, free all created objects,
including the one being built */
void mu_opool_free (mu_opool_t pool, void *obj);
/* Destroy the pool, reclaim any memory associated with it. */
void mu_opool_destroy (mu_opool_t *popool);
......@@ -80,6 +86,10 @@ void *mu_opool_head (mu_opool_t opool, size_t *psize);
return p; */
void *mu_opool_finish (mu_opool_t opool, size_t *psize);
/* Append SIZE bytes from DATA to the pool and return the pointer to the
created object. */
void *mu_opool_dup (mu_opool_t pool, void const *data, size_t size);
int mu_opool_get_iterator (mu_opool_t opool, mu_iterator_t *piterator);
#endif
......
......@@ -686,7 +686,7 @@ display_stream_mailcap (const char *ident, mu_stream_t stream, mu_header_t hdr,
mailcap_path = mailcap_path_tmp;
}
mu_opool_create (&expand_pool, 1);
mu_opool_create (&expand_pool, MU_OPOOL_ENOMEMABRT);
ws.ws_delim = ":";
if (mu_wordsplit (mailcap_path, &ws,
......
......@@ -41,11 +41,11 @@ struct mu_opool_bucket
struct _mu_opool
{
int memerr;
size_t bucket_size;
size_t itr_count;
struct mu_opool_bucket *head, *tail;
struct mu_opool_bucket *free;
int flags; /* Flag bits */
size_t bucket_size; /* Default bucket size */
size_t itr_count; /* Number of iterators created for this pool */
struct mu_opool_bucket *bkt_head, *bkt_tail;
struct mu_opool_bucket *bkt_fini; /* List of finished objects */
};
static struct mu_opool_bucket *
......@@ -54,7 +54,7 @@ alloc_bucket (struct _mu_opool *opool, size_t size)
struct mu_opool_bucket *p = malloc (sizeof (*p) + size);
if (!p)
{
if (opool->memerr)
if (opool->flags & MU_OPOOL_ENOMEMABRT)
mu_alloc_die ();
}
else
......@@ -73,11 +73,11 @@ alloc_pool (mu_opool_t opool, size_t size)
struct mu_opool_bucket *p = alloc_bucket (opool, opool->bucket_size);
if (!p)
return ENOMEM;
if (opool->tail)
opool->tail->next = p;
if (opool->bkt_tail)
opool->bkt_tail->next = p;
else
opool->head = p;
opool->tail = p;
opool->bkt_head = p;
opool->bkt_tail = p;
return 0;
}
......@@ -86,32 +86,32 @@ copy_chars (mu_opool_t opool, const char *str, size_t n, size_t *psize)
{
size_t rest;
if (!opool->head || opool->tail->level == opool->tail->size)
if (!opool->bkt_head || opool->bkt_tail->level == opool->bkt_tail->size)
if (alloc_pool (opool, opool->bucket_size))
return ENOMEM;
rest = opool->tail->size - opool->tail->level;
rest = opool->bkt_tail->size - opool->bkt_tail->level;
if (n > rest)
n = rest;
memcpy (opool->tail->buf + opool->tail->level, str, n);
opool->tail->level += n;
memcpy (opool->bkt_tail->buf + opool->bkt_tail->level, str, n);
opool->bkt_tail->level += n;
*psize = n;
return 0;
}
int
mu_opool_create (mu_opool_t *pret, int memerr)
mu_opool_create (mu_opool_t *pret, int flags)
{
struct _mu_opool *x = malloc (sizeof (x[0]));
if (!x)
{
if (memerr)
if (flags & MU_OPOOL_ENOMEMABRT)
mu_alloc_die ();
return ENOMEM;
}
x->memerr = memerr;
x->flags = flags;
x->bucket_size = MU_OPOOL_BUCKET_SIZE;
x->itr_count = 0;
x->head = x->tail = x->free = 0;
x->bkt_head = x->bkt_tail = x->bkt_fini = NULL;
*pret = x;
return 0;
}
......@@ -140,11 +140,11 @@ mu_opool_clear (mu_opool_t opool)
if (!opool)
return;
if (opool->tail)
if (opool->bkt_tail)
{
opool->tail->next = opool->free;
opool->free = opool->head;
opool->head = opool->tail = NULL;
opool->bkt_tail->next = opool->bkt_fini;
opool->bkt_fini = opool->bkt_head;
opool->bkt_head = opool->bkt_tail = NULL;
}
}
......@@ -156,15 +156,15 @@ mu_opool_destroy (mu_opool_t *popool)
{
mu_opool_t opool = *popool;
mu_opool_clear (opool);
for (p = opool->free; p; )
for (p = opool->bkt_fini; p; )
{
struct mu_opool_bucket *next = p->next;
free (p);
p = next;
}
free (opool);
*popool = NULL;
}
*popool = NULL;
}
int
......@@ -174,13 +174,13 @@ mu_opool_alloc (mu_opool_t opool, size_t size)
{
size_t rest;
if (!opool->head || opool->tail->level == opool->tail->size)
if (!opool->bkt_head || opool->bkt_tail->level == opool->bkt_tail->size)
if (alloc_pool (opool, opool->bucket_size))
return ENOMEM;
rest = opool->tail->size - opool->tail->level;
rest = opool->bkt_tail->size - opool->bkt_tail->level;
if (size < rest)
rest = size;
opool->tail->level += rest;
opool->bkt_tail->level += rest;
size -= rest;
}
return 0;
......@@ -218,7 +218,7 @@ mu_opool_size (mu_opool_t opool)
{
size_t size = 0;
struct mu_opool_bucket *p;
for (p = opool->head; p; p = p->next)
for (p = opool->bkt_head; p; p = p->next)
size += p->level;
return size;
}
......@@ -230,7 +230,7 @@ mu_opool_copy (mu_opool_t opool, void *buf, size_t size)
size_t total = 0;
struct mu_opool_bucket *p;
for (p = opool->head; p && total < size; p = p->next)
for (p = opool->bkt_head; p && total < size; p = p->next)
{
size_t cpsize = size - total;
if (cpsize > p->level)
......@@ -249,27 +249,28 @@ mu_opool_coalesce (mu_opool_t opool, size_t *psize)
if (opool->itr_count)
return MU_ERR_FAILURE;
if (opool->head && opool->head->next == NULL)
size = opool->head->level;
else {
struct mu_opool_bucket *bucket;
struct mu_opool_bucket *p;
if (opool->bkt_head && opool->bkt_head->next == NULL)
size = opool->bkt_head->level;
else
{
struct mu_opool_bucket *bucket;
struct mu_opool_bucket *p;
size = mu_opool_size (opool);
size = mu_opool_size (opool);
bucket = alloc_bucket (opool, size);
if (!bucket)
return ENOMEM;
for (p = opool->head; p; )
{
struct mu_opool_bucket *next = p->next;
memcpy (bucket->buf + bucket->level, p->buf, p->level);
bucket->level += p->level;
free (p);
p = next;
}
opool->head = opool->tail = bucket;
}
bucket = alloc_bucket (opool, size);
if (!bucket)
return ENOMEM;
for (p = opool->bkt_head; p; )
{
struct mu_opool_bucket *next = p->next;
memcpy (bucket->buf + bucket->level, p->buf, p->level);
bucket->level += p->level;
free (p);
p = next;
}
opool->bkt_head = opool->bkt_tail = bucket;
}
if (psize)
*psize = size;
return 0;
......@@ -278,9 +279,9 @@ mu_opool_coalesce (mu_opool_t opool, size_t *psize)
void *
mu_opool_head (mu_opool_t opool, size_t *psize)
{
if (*psize)
*psize = opool->head ? opool->head->level : 0;
return opool->head ? opool->head->buf : NULL;
if (psize)
*psize = opool->bkt_head ? opool->bkt_head->level : 0;
return opool->bkt_head ? opool->bkt_head->buf : NULL;
}
void *
......@@ -289,7 +290,48 @@ mu_opool_finish (mu_opool_t opool, size_t *psize)
if (mu_opool_coalesce (opool, psize))
return NULL;
mu_opool_clear (opool);
return opool->free->buf;
return opool->bkt_fini->buf;
}
void
mu_opool_free (mu_opool_t pool, void *obj)
{
if (!pool)
return;
if (!obj)
{
if (pool->bkt_head)
mu_opool_finish (pool, NULL);
while (pool->bkt_fini)
{
struct mu_opool_bucket *next = pool->bkt_fini->next;
free (pool->bkt_fini);
pool->bkt_fini = next;
}
}
else
{
struct mu_opool_bucket *bucket = pool->bkt_fini, **pprev = &pool->bkt_fini;
while (bucket)
{
if (bucket->buf == obj)
{
*pprev = bucket->next;
free (bucket);
return;
}
pprev = &bucket->next;
bucket = bucket->next;
}
}
}
void *
mu_opool_dup (mu_opool_t pool, void const *data, size_t size)
{
if (mu_opool_append (pool, data, size))
return NULL;
return mu_opool_finish (pool, NULL);
}
int
......@@ -314,20 +356,20 @@ mu_opool_union (mu_opool_t *pdst, mu_opool_t *psrc)
else
dst = *pdst;
if (dst->tail)
dst->tail->next = src->head;
if (dst->bkt_tail)
dst->bkt_tail->next = src->bkt_head;
else
dst->head = src->head;
dst->tail = src->tail;
dst->bkt_head = src->bkt_head;
dst->bkt_tail = src->bkt_tail;
if (src->free)
if (src->bkt_fini)
{
struct mu_opool_bucket *p;
for (p = src->free; p->next; p = p->next)
for (p = src->bkt_fini; p->next; p = p->next)
;
p->next = dst->free;
dst->free = src->free;
p->next = dst->bkt_fini;
dst->bkt_fini = src->bkt_fini;
}
free (src);
......@@ -347,7 +389,7 @@ static int
opitr_first (void *owner)
{
struct opool_iterator *itr = owner;
itr->cur = itr->opool->head;
itr->cur = itr->opool->bkt_head;
return 0;
}
......@@ -434,7 +476,7 @@ mu_opool_get_iterator (mu_opool_t opool, mu_iterator_t *piterator)
if (!itr)
return ENOMEM;
itr->opool = opool;
itr->cur = opool->head;
itr->cur = opool->bkt_head;
status = mu_iterator_create (&iterator, itr);
if (status)
......
......@@ -200,7 +200,7 @@ void
_mu_line_begin ()
{
if (!pool)
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
else
mu_opool_clear (pool);
}
......
......@@ -1110,7 +1110,7 @@ mu_cfg_tree_create (struct mu_cfg_tree **ptree)
struct mu_cfg_tree *tree = calloc (1, sizeof *tree);
if (!tree)
return errno;
mu_opool_create (&tree->pool, 1);
mu_opool_create (&tree->pool, MU_OPOOL_ENOMEMABRT);
*ptree = tree;
return 0;
}
......
......@@ -111,7 +111,7 @@ mu_url_sget_name (const mu_url_t url, const char **retptr)
char *ptr, *newname;
size_t size;
rc = mu_opool_create (&pool, 0);
rc = mu_opool_create (&pool, MU_OPOOL_DEFAULT);
if (rc)
return rc;
rc = url_reconstruct_to_pool (url, pool);
......
......@@ -654,7 +654,7 @@ pop_header_blurb (mu_stream_t stream, size_t maxlines,
size_t n;
size_t nlines = 0;
status = mu_opool_create (&opool, 0);
status = mu_opool_create (&opool, MU_OPOOL_DEFAULT);
if (status)
return status;
......
......@@ -678,7 +678,7 @@ main (int argc, char **argv)
mu_attribute_set_deleted (attr);
}
mu_mailbox_expunge (tmpbox);
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
}
else
tmpbox = mbox;
......
......@@ -499,7 +499,7 @@ mh_format_parse (char *format_str, mh_format_t *fmt)
if (p)
yydebug = 1;
start = curp = format_str;
mu_opool_create (&tokpool, 1);
mu_opool_create (&tokpool, MU_OPOOL_ENOMEMABRT);
format.prog = NULL;
format.progsize = 0;
pc = 0;
......
......@@ -490,7 +490,7 @@ mh_format (mh_format_t *fmt, mu_message_t msg, size_t msgno,
mach.width = width - 1; /* Count the newline */
mach.pc = 1;
mu_opool_create (&mach.pool, 1);
mu_opool_create (&mach.pool, MU_OPOOL_ENOMEMABRT);
mu_list_create (&mach.addrlist);
reset_fmt_defaults (&mach);
......
......@@ -461,7 +461,7 @@ mhn_compose_command (char *typestr, char *typeargs, int *flags, char *file)
%F %f, and stdout is not redirected
%s subtype */
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
p = mu_str_skip_class (str, MU_CTYPE_SPACE);
......@@ -642,7 +642,7 @@ mhn_show_command (mu_message_t msg, msg_part_t part, int *flags,
%s subtype
%d content description */
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
p = mu_str_skip_class (str, MU_CTYPE_SPACE);
......@@ -814,7 +814,7 @@ mhn_store_command (mu_message_t msg, msg_part_t part, const char *name,
%p part
%s subtype */
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
for (p = str; *p; p++)
{
......@@ -1883,7 +1883,7 @@ parse_type_command (char **pcmd, struct compose_env *env, mu_header_t hdr)
return 1;
}
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
mu_opool_appendz (pool, type);
mu_opool_append_char (pool, '/');
......@@ -2050,7 +2050,7 @@ edit_extern (char *cmd, struct compose_env *env, mu_message_t *msg, int level)
mu_message_get_header (*msg, &hdr);
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
mu_opool_append (pool, EXTCONTENT, sizeof (EXTCONTENT) - 1);
*--rest = ';'; /* FIXME */
rc = parse_content_type (env, pool, &rest, &id, NULL);
......
......@@ -156,7 +156,7 @@ main (int argc, char **argv)
mu_opool_t opool;
const char *prompt = name;
mu_opool_create (&opool, 1);
mu_opool_create (&opool, MU_OPOOL_ENOMEMABRT);
do
{
size_t len;
......
......@@ -73,7 +73,7 @@ set_fcc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
if (!has_fcc)
{
mu_opool_create (&fcc_pool, 1);
mu_opool_create (&fcc_pool, MU_OPOOL_ENOMEMABRT);
has_fcc = 1;
}
else
......
......@@ -84,7 +84,7 @@ mh_whatnow_env_to_environ (struct mh_whatnow_env *wh)
int mrange = 0;
const char *s;
mu_opool_create (&opool, 1);
mu_opool_create (&opool, MU_OPOOL_ENOMEMABRT);
mu_list_get_iterator (wh->anno_list, &itr);
for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr))
......
......@@ -172,7 +172,7 @@ mimetypes_open (const char *name)
return -1;
}
line_num = 1;
mu_opool_create (&pool, 1);
mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
return 0;
}
......
......@@ -610,7 +610,7 @@ newfmt_init (struct xfer_format *fmt, const char *version,
else
{
mu_opool_t pool;
rc = mu_opool_create (&pool, 0);
rc = mu_opool_create (&pool, MU_OPOOL_DEFAULT);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_opool_create",
......