diff --git a/configure.ac b/configure.ac index 40e2c34..3dee3e2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(libsexpr, 1.3) +AC_INIT(libsexpr, 1.3.0) AC_CONFIG_HEADERS([config.h]) diff --git a/debian/changelog b/debian/changelog index 005b2f5..f50a2db 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -libsexpr (1.2-1) unstable; urgency=low +libsexpr (1.3.0) stable; urgency=low * Initial release (Closes: #nnnn) diff --git a/debian/control b/debian/control index eb42e36..4e82cff 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: libsexpr Priority: extra Maintainer: Alexander Vdolainen -Build-Depends: debhelper (>= 8.0.0), autotools-dev +Build-Depends: debhelper (>= 8.0.0), autotools-dev, libc-dev Standards-Version: 3.9.3 Section: libs Homepage: http://askele.com/software @@ -11,7 +11,7 @@ Homepage: http://askele.com/software Package: libsexpr-dev Section: libdevel Architecture: any -Depends: libsexpr (= ${binary:Version}) +Depends: libsexpr (= ${binary:Version}), libc-dev Description: Development files for libsexpr Development files for library working with S-expressions diff --git a/debian/shlibs.local.ex b/debian/shlibs.local.ex index da0d48a..caeda72 100644 --- a/debian/shlibs.local.ex +++ b/debian/shlibs.local.ex @@ -1 +1 @@ -liblibsexpr 1.2 libsexpr (>> 1.2-0), libsexpr (<< 1.2-99) +liblibsexpr 1.3.0 libsexpr (>> 1.3.0), libsexpr (<< 1.3.99) diff --git a/lib/Makefile.am b/lib/Makefile.am index ec8397d..6a4067a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -4,7 +4,6 @@ AM_CPPFLAGS = \ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \ -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ -DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \ - -D_NO_MEMORY_MANAGEMENT_ \ $(LIBTDATA_CFLAGS) -I../include AM_CFLAGS =\ diff --git a/lib/parser.c b/lib/parser.c index ce07034..5bb837c 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -40,11 +40,16 @@ LA-CC-04-094 #include #include +/* we need a locks in this case and we don't have ability to change API */ +#ifndef _NO_MEMORY_MANAGEMENT_ +#include +#endif + /* * constants related to atom buffer sizes and growth. */ static size_t sexp_val_start_size = 256; -static size_t sexp_val_grow_size = 64; +static size_t sexp_val_grow_size = 128; /* * Function for tuning growth parameters. @@ -79,6 +84,7 @@ parse_data_t; */ #ifndef _NO_MEMORY_MANAGEMENT_ faststack_t *pd_cache; +pthread_mutex_t pd_cache_lock; #endif /** @@ -91,6 +97,7 @@ faststack_t *pd_cache; */ #ifndef _NO_MEMORY_MANAGEMENT_ faststack_t *sexp_t_cache; +pthread_mutex_t sexp_cache_lock; #endif /** @@ -115,23 +122,28 @@ sexp_t_allocate(void) { if (sexp_t_cache == NULL) { sexp_t_cache = make_stack(); + pthread_mutex_init(&sexp_cache_lock, NULL); if (sexp_t_cache == NULL) { sexp_errno = SEXP_ERR_MEMORY; return NULL; } + pthread_mutex_lock(&sexp_cache_lock); #ifdef __cplusplus sx = (sexp_t *)sexp_malloc(sizeof(sexp_t)); #else sx = sexp_malloc(sizeof(sexp_t)); #endif if (sx == NULL) { + pthread_mutex_unlock(&sexp_cache_lock); sexp_errno = SEXP_ERR_MEMORY; return NULL; } sx->next = sx->list = NULL; + pthread_mutex_unlock(&sexp_cache_lock); } else { + pthread_mutex_lock(&sexp_cache_lock); if (empty_stack(sexp_t_cache)) { #ifdef __cplusplus sx = (sexp_t *)sexp_malloc(sizeof(sexp_t)); @@ -139,6 +151,7 @@ sexp_t_allocate(void) { sx = sexp_malloc(sizeof(sexp_t)); #endif if (sx == NULL) { + pthread_mutex_unlock(&sexp_cache_lock); sexp_errno = SEXP_ERR_MEMORY; return NULL; } @@ -148,6 +161,7 @@ sexp_t_allocate(void) { l = pop(sexp_t_cache); sx = (sexp_t *)l->data; } + pthread_mutex_unlock(&sexp_cache_lock); } return sx; @@ -173,6 +187,7 @@ sexp_t_deallocate(sexp_t *s) { if (sexp_t_cache == NULL) { sexp_t_cache = make_stack(); + pthread_mutex_init(&sexp_cache_lock, NULL); if (sexp_t_cache == NULL) { /**** HOW DO WE GET THE USER TO KNOW SOMETHING HAPPENED? ****/ @@ -185,6 +200,7 @@ sexp_t_deallocate(sexp_t *s) { return; } } + pthread_mutex_lock(&sexp_cache_lock); s->list = s->next = NULL; @@ -193,8 +209,10 @@ sexp_t_deallocate(sexp_t *s) { } s->val = NULL; + memset(s, 0, sizeof(sexp_t)); sexp_t_cache = push(sexp_t_cache, s); + pthread_mutex_unlock(&sexp_cache_lock); } #endif @@ -210,6 +228,7 @@ void sexp_cleanup(void) { stack_lvl_t *l; if (pd_cache != NULL) { + pthread_mutex_lock(&pd_cache_lock); l = pd_cache->top; while (l != NULL) { sexp_free(l->data,sizeof(parse_data_t)); @@ -217,15 +236,20 @@ void sexp_cleanup(void) { } destroy_stack(pd_cache); pd_cache = NULL; + pthread_mutex_unlock(&pd_cache_lock); + pthread_mutex_destroy(&pd_cache_lock); } if (sexp_t_cache != NULL) { + pthread_mutex_lock(&sexp_cache_lock); l = sexp_t_cache->top; while (l != NULL) { sexp_free(l->data,sizeof(sexp_t)); l = l->below; } destroy_stack(sexp_t_cache); + pthread_mutex_lock(&sexp_cache_lock); + pthread_mutex_destroy(&sexp_cache_lock); sexp_t_cache = NULL; } } @@ -248,13 +272,14 @@ pd_allocate(void) { stack_lvl_t *l; if (pd_cache == NULL) { + pthread_mutex_init(&pd_cache_lock, NULL); pd_cache = make_stack(); - + if (pd_cache == NULL) { sexp_errno = SEXP_ERR_MEMORY; return NULL; } - + pthread_mutex_lock(&pd_cache_lock); #ifdef __cplusplus p = (parse_data_t *)sexp_malloc(sizeof(parse_data_t)); #else @@ -265,8 +290,9 @@ pd_allocate(void) { sexp_errno = SEXP_ERR_MEMORY; return NULL; } - + pthread_mutex_unlock(&pd_cache_lock); } else { + pthread_mutex_lock(&pd_cache_lock); if (empty_stack(pd_cache)) { #ifdef __cplusplus p = (parse_data_t *)sexp_malloc(sizeof(parse_data_t)); @@ -276,12 +302,14 @@ pd_allocate(void) { if (p == NULL) { sexp_errno = SEXP_ERR_MEMORY; + pthread_mutex_unlock(&pd_cache_lock); return NULL; } } else { l = pop(pd_cache); p = (parse_data_t *)l->data; } + pthread_mutex_unlock(&pd_cache_lock); } return p; @@ -301,14 +329,19 @@ void pd_deallocate(parse_data_t *p) { if (pd_cache == NULL) { pd_cache = make_stack(); + pthread_mutex_init(&pd_cache_lock, NULL); if (pd_cache == NULL) { sexp_free(p, sizeof(parse_data_t)); sexp_errno = SEXP_ERR_MEMORY; return; } } + pthread_mutex_lock(&pd_cache_lock); + memset(p, 0, sizeof(parse_data_t)); pd_cache = push(pd_cache, p); + + pthread_mutex_unlock(&pd_cache_lock); } #endif /* _NO_MEMORY_MANAGEMENT_ */ @@ -509,9 +542,9 @@ init_continuation(char *str) /* allocate atom buffer */ #ifdef __cplusplus - cc->val = (char *)sexp_malloc(sizeof(char)*sexp_val_start_size); + cc->val = (char *)sexp_calloc(1, sizeof(char)*sexp_val_start_size); #else - cc->val = sexp_malloc(sizeof(char)*sexp_val_start_size); + cc->val = sexp_calloc(1, sizeof(char)*sexp_val_start_size); #endif if (cc->val == NULL) { @@ -599,6 +632,12 @@ iparse_sexp (char *s, size_t len, pcont_t *cc) { * cparse_sexp */ pcont_t *eparse_sexp (char *str, size_t len, pcont_t *lc); +#ifdef REGISTEROPTIMIZAITON +#define REGISTER register +#else +#define REGISTER +#endif + /** * Continuation based parser - the guts of the package. */ @@ -607,17 +646,17 @@ cparse_sexp (char *str, size_t len, pcont_t *lc) { char *t = NULL; char *s = NULL; - register size_t binexpected = 0; - register size_t binread = 0; - register parsermode_t mode = PARSER_NORMAL; - register size_t val_allocated = 0; - register unsigned int squoted = 0; - register size_t val_used = 0; - register unsigned int state = 1; - register unsigned int depth = 0; - register unsigned int qdepth = 0; - register unsigned int elts = 0; - register unsigned int esc = 0; + REGISTER size_t binexpected = 0; + REGISTER size_t binread = 0; + REGISTER parsermode_t mode = PARSER_NORMAL; + REGISTER size_t val_allocated = 0; + REGISTER unsigned int squoted = 0; + REGISTER size_t val_used = 0; + REGISTER unsigned int state = 1; + REGISTER unsigned int depth = 0; + REGISTER unsigned int qdepth = 0; + REGISTER unsigned int elts = 0; + REGISTER unsigned int esc = 0; pcont_t *cc = NULL; char *val = NULL; char *vcur = NULL;