From: Robert Spalek Date: Thu, 20 Apr 2006 16:24:08 +0000 (+0200) Subject: cf_pool exported, journal not mandatory, and simplified swapping data X-Git-Tag: holmes-import~645^2~11^2~101 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=3030ed85a1d02ba1c11e186b1b8adfa44f1deade;p=libucw.git cf_pool exported, journal not mandatory, and simplified swapping data --- diff --git a/lib/conf2.c b/lib/conf2.c index bdba4456..88e17fc7 100644 --- a/lib/conf2.c +++ b/lib/conf2.c @@ -18,27 +18,28 @@ /* Memory allocation */ +struct mempool *cf_pool; // current pool for loading new configuration static struct old_pools { struct old_pools *prev; struct mempool *pool; -} *pools; +} *pools; // link-list of older cf_pool's void * cf_malloc(uns size) { - return mp_alloc(pools->pool, size); + return mp_alloc(cf_pool, size); } void * cf_malloc_zero(uns size) { - return mp_alloc_zero(pools->pool, size); + return mp_alloc_zero(cf_pool, size); } byte * cf_strdup(byte *s) { - return mp_strdup(pools->pool, s); + return mp_strdup(cf_pool, s); } byte * @@ -46,16 +47,17 @@ cf_printf(char *fmt, ...) { va_list args; va_start(args, fmt); - byte *res = mp_vprintf(pools->pool, fmt, args); + byte *res = mp_vprintf(cf_pool, fmt, args); va_end(args); return res; } /* Undo journal */ +uns cf_need_journal; // some programs do not need journal static struct journal_item { struct journal_item *prev; - void *ptr; + byte *ptr; uns len; byte copy[0]; } *journal; @@ -63,6 +65,8 @@ static struct journal_item { void cf_journal_block(void *ptr, uns len) { + if (!cf_need_journal) + return; struct journal_item *ji = cf_malloc(sizeof(struct journal_item) + len); ji->prev = journal; ji->ptr = ptr; @@ -76,57 +80,60 @@ journal_swap(void) // swaps the contents of the memory and the journal, and reverses the list { struct journal_item *curr, *prev, *next; - uns max_len = 0; - for (curr=journal; curr; curr=curr->prev) - max_len = MAX(max_len, curr->len); - byte *buf = xmalloc(max_len); for (next=NULL, curr=journal; curr; next=curr, curr=prev) { prev = curr->prev; curr->prev = next; - memcpy(buf, curr->copy, curr->len); - memcpy(curr->copy, curr->ptr, curr->len); - memcpy(curr->ptr, buf, curr->len); + for (uns i=0; ilen; i++) + { + byte x = curr->copy[i]; + curr->copy[i] = curr->ptr[i]; + curr->ptr[i] = x; + } } journal = next; - xfree(buf); } static struct journal_item * journal_new_section(uns new_pool) { if (new_pool) - { - struct old_pools *oldp = pools; - struct mempool *mp = mp_new(1<<14); - pools = mp_alloc(mp, sizeof(struct old_pools)); - pools->prev = oldp; - pools->pool = mp; - } + cf_pool = mp_new(1<<14); struct journal_item *oldj = journal; journal = NULL; return oldj; } static void -journal_commit_section(struct journal_item *oldj) +journal_commit_section(uns new_pool, struct journal_item *oldj) { - struct journal_item **j = &journal; - while (*j) - j = &(*j)->prev; - *j = oldj; + if (new_pool) + { + struct old_pools *p = cf_malloc(sizeof(struct old_pools)); + p->prev = pools; + p->pool = cf_pool; + pools = p; + } + if (oldj) + { + struct journal_item **j = &journal; + while (*j) + j = &(*j)->prev; + *j = oldj; + } } static void -journal_rollback_section(uns new_pool, struct journal_item *oldj) +journal_rollback_section(uns new_pool, struct journal_item *oldj, byte *msg) { + if (!cf_need_journal) + die("Cannot rollback the configuration, because the journal is disabled. Error: %s", msg); journal_swap(); journal = oldj; if (new_pool) { - struct old_pools *oldp = pools; - pools = pools->prev; - mp_delete(oldp->pool); + mp_delete(cf_pool); + cf_pool = pools ? pools->pool : NULL; } } @@ -139,23 +146,22 @@ byte * cf_reload(byte *file) { journal_swap(); - struct old_pools *oldp = pools; - pools = NULL; - struct journal_item *oldj = journal_new_section(1); byte *msg = load_file(file); - if (msg) + if (!msg) { - journal_rollback_section(1, oldj); - pools = oldp; - journal_swap(); - } - else - for (struct old_pools *p=oldp; p; p=oldp) + for (struct old_pools *p=pools; p; p=pools) { - oldp = p->prev; + pools = p->prev; mp_delete(p->pool); } + journal_commit_section(1, NULL); + } + else + { + journal_rollback_section(1, oldj, msg); + journal_swap(); + } return msg; } @@ -165,9 +171,9 @@ cf_load(byte *file) struct journal_item *oldj = journal_new_section(1); byte *msg = load_file(file); if (!msg) - journal_commit_section(oldj); + journal_commit_section(1, oldj); else - journal_rollback_section(1, oldj); + journal_rollback_section(1, oldj, msg); return msg; } @@ -177,9 +183,9 @@ cf_set(byte *string) struct journal_item *oldj = journal_new_section(0); byte *msg = load_string(string); if (!msg) - journal_commit_section(oldj); + journal_commit_section(0, oldj); else - journal_rollback_section(0, oldj); + journal_rollback_section(0, oldj, msg); return msg; } diff --git a/lib/conf2.h b/lib/conf2.h index eb4230df..cd2deb51 100644 --- a/lib/conf2.h +++ b/lib/conf2.h @@ -93,12 +93,15 @@ struct clist; // creates a static instance of a dynamic array /* Memory allocation */ +struct mempool; +extern struct mempool *cf_pool; void *cf_malloc(uns size); void *cf_malloc_zero(uns size); byte *cf_strdup(byte *s); byte *cf_printf(char *fmt, ...); /* Undo journal for error recovery */ +extern uns cf_need_journal; void cf_journal_block(void *ptr, uns len); /* Safe reloading and loading of configuration files */