diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2016-10-30 10:50:07 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2016-10-30 10:50:07 +0200 |
commit | b54540cbbc95069b6d073246a575683170920275 (patch) | |
tree | bf7d188d6ae5fa434be6a71b9c415b0d163b8aab | |
parent | c6848f52257191abb36b694be61ce333a8992b4b (diff) | |
download | mailutils-b54540cbbc95069b6d073246a575683170920275.tar.gz mailutils-b54540cbbc95069b6d073246a575683170920275.tar.bz2 |
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.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | comsat/action.c | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/mailutils/opool.h | 18 | ||||
-rw-r--r-- | lib/mailcap.c | 2 | ||||
-rw-r--r-- | libmailutils/base/opool.c | 166 | ||||
-rw-r--r-- | libmailutils/cfg/lexer.l | 2 | ||||
-rw-r--r-- | libmailutils/cfg/parser.y | 2 | ||||
-rw-r--r-- | libmailutils/url/urlstr.c | 2 | ||||
-rw-r--r-- | libproto/pop/mbox.c | 2 | ||||
-rw-r--r-- | mh/burst.c | 2 | ||||
-rw-r--r-- | mh/mh_fmtgram.y | 2 | ||||
-rw-r--r-- | mh/mh_format.c | 2 | ||||
-rw-r--r-- | mh/mhn.c | 10 | ||||
-rw-r--r-- | mh/prompter.c | 2 | ||||
-rw-r--r-- | mh/repl.c | 2 | ||||
-rw-r--r-- | mh/whatnowenv.c | 2 | ||||
-rw-r--r-- | mimeview/mimetypes.l | 2 | ||||
-rw-r--r-- | mu/dbm.c | 2 |
19 files changed, 140 insertions, 88 deletions
@@ -1,11 +1,11 @@ -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 diff --git a/comsat/action.c b/comsat/action.c index 0582637b2..dc5703274 100644 --- a/comsat/action.c +++ b/comsat/action.c @@ -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) diff --git a/configure.ac b/configure.ac index b8161ec7a..92ac4a15e 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/include/mailutils/opool.h b/include/mailutils/opool.h index bc68e4aab..63c5a38f2 100644 --- a/include/mailutils/opool.h +++ b/include/mailutils/opool.h @@ -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 diff --git a/lib/mailcap.c b/lib/mailcap.c index 02f189413..503390c8e 100644 --- a/lib/mailcap.c +++ b/lib/mailcap.c @@ -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, diff --git a/libmailutils/base/opool.c b/libmailutils/base/opool.c index 77257f2c5..5e19081ac 100644 --- a/libmailutils/base/opool.c +++ b/libmailutils/base/opool.c @@ -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) diff --git a/libmailutils/cfg/lexer.l b/libmailutils/cfg/lexer.l index b6c49ecc1..2ecefce87 100644 --- a/libmailutils/cfg/lexer.l +++ b/libmailutils/cfg/lexer.l @@ -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); } diff --git a/libmailutils/cfg/parser.y b/libmailutils/cfg/parser.y index a530f10f5..9ad8e8d60 100644 --- a/libmailutils/cfg/parser.y +++ b/libmailutils/cfg/parser.y @@ -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; } diff --git a/libmailutils/url/urlstr.c b/libmailutils/url/urlstr.c index c57576a03..34c69f36a 100644 --- a/libmailutils/url/urlstr.c +++ b/libmailutils/url/urlstr.c @@ -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); diff --git a/libproto/pop/mbox.c b/libproto/pop/mbox.c index 64e375a81..b877b6f98 100644 --- a/libproto/pop/mbox.c +++ b/libproto/pop/mbox.c @@ -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; diff --git a/mh/burst.c b/mh/burst.c index 173a8f719..4d5a3b791 100644 --- a/mh/burst.c +++ b/mh/burst.c @@ -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; diff --git a/mh/mh_fmtgram.y b/mh/mh_fmtgram.y index 018bdcebf..9b690b7b9 100644 --- a/mh/mh_fmtgram.y +++ b/mh/mh_fmtgram.y @@ -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; diff --git a/mh/mh_format.c b/mh/mh_format.c index 77e4e8531..c74a260b9 100644 --- a/mh/mh_format.c +++ b/mh/mh_format.c @@ -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); diff --git a/mh/prompter.c b/mh/prompter.c index 5c4405fc5..2efde12f0 100644 --- a/mh/prompter.c +++ b/mh/prompter.c @@ -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 diff --git a/mh/whatnowenv.c b/mh/whatnowenv.c index f4af15622..81b9368ce 100644 --- a/mh/whatnowenv.c +++ b/mh/whatnowenv.c @@ -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)) diff --git a/mimeview/mimetypes.l b/mimeview/mimetypes.l index 995b8de6f..9cdbf9d21 100644 --- a/mimeview/mimetypes.l +++ b/mimeview/mimetypes.l @@ -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", |