diff options
| author | Thomas Knudsen <thokn@sdfe.dk> | 2017-09-27 13:56:34 +0200 |
|---|---|---|
| committer | Thomas Knudsen <thokn@sdfe.dk> | 2017-10-06 11:39:27 +0200 |
| commit | 664577ced6a8e4074b1f53af82b5ae5d1d189eac (patch) | |
| tree | a29d4a6c0842bb87df63fc913502c3b6c5b097a5 /src/pj_malloc.c | |
| parent | 0495fdca92fc620d44572ce1e4e871f57f968198 (diff) | |
| download | PROJ-664577ced6a8e4074b1f53af82b5ae5d1d189eac.tar.gz PROJ-664577ced6a8e4074b1f53af82b5ae5d1d189eac.zip | |
Enable default destructor for all PJ objects.
In most cases memory deallocation is completely removed from the
code since it can be handled by the default destructor. In a few
special cases a local destructor overrides the default destructor
and makes sure that locally allocated memored is cleaned up correctly.
Move all deallocation from pj_free to pj_default_destructor
Rename pj_latlong.c to fit with the conventional format PJ_latlong.c - freeup was missed here due to wrong naming
Clean up pj_init to avoid double deallocation; Also resolve #576 by adding z_0 and t_0 options in pj_init, while cleaning
Add a prototype for dealloc_params
Added missing errno.h include in pj_ctx.c
Temporarily removing ob_tran from testvarious, to be sure that is where the trouble is
Make PJ_ob_tran.c use proper initialization for the chained projection
proj=ob_tran: make it clear, that we disallow ellipsoidal projections, and, for improved backwards compatibility, turns off default settings, which could inject unwanted ellipsoid definitions
... then also remove the ellipsoid definition from the testvarious test case - which is probably buggy anyway
Work around cs2cs spherical init bug in testvarious; Forbid defs for ob_tran in pj_init
Diffstat (limited to 'src/pj_malloc.c')
| -rw-r--r-- | src/pj_malloc.c | 91 |
1 files changed, 71 insertions, 20 deletions
diff --git a/src/pj_malloc.c b/src/pj_malloc.c index 52cf7deb..9c69257f 100644 --- a/src/pj_malloc.c +++ b/src/pj_malloc.c @@ -40,7 +40,7 @@ ** projection system memory allocation/deallocation call with custom ** application procedures. */ -#include <projects.h> +#include "projects.h" #include <errno.h> /**********************************************************************/ @@ -52,30 +52,43 @@ https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=86420. It seems, that pj_init and similar functions incorrectly (under debian/glibs-2.3.2) assume that pj_malloc resets errno after success. pj_malloc tries to mimic this. -***********************************************************************/ - int old_errno = errno; - void *res = malloc(size); - if ( res && !old_errno ) - errno = 0; - return res; -} -/**********************************************************************/ -void pj_dalloc(void *ptr) { -/**********************************************************************/ - free(ptr); +NOTE (2017-09-29): The problem described at the bugzilla page +referred to above, is most likely a case of someone not +understanding the proper usage of errno. We should review +whether "the problem is actually a problem" in PROJ.4 code. + +Library specific allocators can be useful, and improve +interoperability, if properly used. That is, by making them +run/initialization time switchable, somewhat like the file i/o +interface. + +But as things stand, we are more likely to get benefit +from reviewing the code for proper errno usage, which is hard, +due to the presence of context local and global pj_errnos. + +Probably, these were introduced in order to support incomplete +implementations of thread local errnos at an early phase of the +implementation of multithreading support in PROJ.4). + +It is likely too late to get rid of contexts, but we can still +benefit from a better usage of errno. +***********************************************************************/ + int old_errno = errno; + void *res = malloc(size); + if ( res && !old_errno ) + errno = 0; + return res; } /**********************************************************************/ void *pj_calloc (size_t n, size_t size) { /*********************************************************************** - pj_calloc is the pj-equivalent of calloc(). It allocates space for an array of <n> elements of size <size>. The array is initialized to zeros. - ***********************************************************************/ void *res = pj_malloc (n*size); if (0==res) @@ -86,9 +99,15 @@ The array is initialized to zeros. /**********************************************************************/ +void pj_dalloc(void *ptr) { +/**********************************************************************/ + free(ptr); +} + + +/**********************************************************************/ void *pj_dealloc (void *ptr) { /*********************************************************************** - pj_dealloc supports the common use case of "clean up and return a null pointer" to signal an error in a multi level allocation: @@ -113,23 +132,55 @@ pointer" to signal an error in a multi level allocation: +/*****************************************************************************/ +void *pj_dealloc_params (projCtx ctx, paralist *start, int errlev) { +/***************************************************************************** + Companion to pj_default_destructor (below). Deallocates a linked list + of "+proj=xxx" initialization parameters. + + Also called from pj_init_ctx when encountering errors before the PJ + proper is allocated. +******************************************************************************/ + paralist *t, *n; + for (t = start; t; t = n) { + n = t->next; + pj_dealloc(t); + } + pj_ctx_set_errno (ctx, errlev); + return (void *) 0; +} + /*****************************************************************************/ void *pj_default_destructor (PJ *P, int errlev) { /* Destructor */ /***************************************************************************** Does memory deallocation for "plain" PJ objects, i.e. that vast majority of PJs where the opaque object does not contain any additionally - allocated memory. + allocated memory below the P->opaque level. ******************************************************************************/ if (0==P) return 0; - if (0!=errlev) - pj_ctx_set_errno (P->ctx, errlev); + + /* free grid lists */ + pj_dealloc( P->gridlist ); + pj_dealloc( P->vgridlist_geoid ); + pj_dealloc( P->catalog_name ); + + /* We used to call pj_dalloc( P->catalog ), but this will leak */ + /* memory. The safe way to clear catalog and grid is to call */ + /* pj_gc_unloadall(pj_get_default_ctx()); and pj_deallocate_grids(); */ + /* TODO: we should probably have a public pj_cleanup() method to do all */ + /* that */ + + /* free the interface to Charles Karney's geodesic library */ + pj_dealloc( P->geod ); - if (0==P->opaque) - return pj_dealloc (P); + /* free parameter list elements */ + pj_dealloc_params (pj_get_ctx(P), P->params, errlev); pj_dealloc (P->opaque); + if (0!=errlev) + pj_ctx_set_errno (pj_get_ctx(P), errlev); return pj_dealloc(P); } |
