diff options
| -rw-r--r-- | src/ctx.cpp | 94 | ||||
| -rw-r--r-- | src/internal.cpp | 2 | ||||
| -rw-r--r-- | src/iso19111/c_api.cpp | 4 | ||||
| -rw-r--r-- | src/log.cpp | 2 | ||||
| -rw-r--r-- | src/proj_internal.h | 24 |
5 files changed, 69 insertions, 57 deletions
diff --git a/src/ctx.cpp b/src/ctx.cpp index 195f3b7f..a94eaf54 100644 --- a/src/ctx.cpp +++ b/src/ctx.cpp @@ -29,12 +29,10 @@ #include <stdlib.h> #include <string.h> +#include <new> + #include "proj_experimental.h" #include "proj_internal.h" -#include "proj_internal.h" - -static projCtx_t default_context; -static volatile int default_context_initialized = 0; /************************************************************************/ /* pj_get_ctx() */ @@ -81,61 +79,68 @@ void proj_assign_context( PJ* pj, PJ_CONTEXT* ctx ) } /************************************************************************/ -/* pj_get_default_ctx() */ +/* createDefault() */ /************************************************************************/ -projCtx pj_get_default_ctx() - +projCtx_t projCtx_t::createDefault() { - /* If already initialized, don't bother locking */ - if( default_context_initialized ) - return &default_context; + projCtx_t ctx; + ctx.debug_level = PJ_LOG_NONE; + ctx.logger = pj_stderr_logger; + ctx.fileapi = pj_get_default_fileapi(); - pj_acquire_lock(); - - /* Ask again, since it may have been initialized in another thread */ - if( !default_context_initialized ) + if( getenv("PROJ_DEBUG") != nullptr ) { - default_context.last_errno = 0; - default_context.debug_level = PJ_LOG_NONE; - default_context.logger = pj_stderr_logger; - default_context.app_data = nullptr; - default_context.fileapi = pj_get_default_fileapi(); - default_context.cpp_context = nullptr; - default_context.use_proj4_init_rules = -1; - default_context.epsg_file_exists = -1; - - if( getenv("PROJ_DEBUG") != nullptr ) - { - if( atoi(getenv("PROJ_DEBUG")) >= -PJ_LOG_DEBUG_MINOR ) - default_context.debug_level = atoi(getenv("PROJ_DEBUG")); - else - default_context.debug_level = PJ_LOG_DEBUG_MINOR; - } - default_context_initialized = 1; + if( atoi(getenv("PROJ_DEBUG")) >= -PJ_LOG_DEBUG_MINOR ) + ctx.debug_level = atoi(getenv("PROJ_DEBUG")); + else + ctx.debug_level = PJ_LOG_DEBUG_MINOR; } + return ctx; +} + +/************************************************************************/ +/* projCtx_t(const projCtx_t& other) */ +/************************************************************************/ - pj_release_lock(); +projCtx_t::projCtx_t(const projCtx_t& other) +{ + debug_level = other.debug_level; + logger = other.logger; + logger_app_data = other.logger_app_data; + fileapi = other.fileapi; + epsg_file_exists = other.epsg_file_exists; +} +/************************************************************************/ +/* pj_get_default_ctx() */ +/************************************************************************/ + +projCtx pj_get_default_ctx() + +{ + // C++11 rules guarantee a thread-safe instanciation. + static projCtx_t default_context(projCtx_t::createDefault()); return &default_context; } /************************************************************************/ +/* ~projCtx_t() */ +/************************************************************************/ + +projCtx_t::~projCtx_t() +{ + proj_context_delete_cpp_context(cpp_context); +} + +/************************************************************************/ /* pj_ctx_alloc() */ /************************************************************************/ projCtx pj_ctx_alloc() { - projCtx ctx = (projCtx_t *) malloc(sizeof(projCtx_t)); - if (nullptr==ctx) - return nullptr; - memcpy( ctx, pj_get_default_ctx(), sizeof(projCtx_t) ); - ctx->last_errno = 0; - ctx->cpp_context = nullptr; - ctx->use_proj4_init_rules = -1; - - return ctx; + return new (std::nothrow) projCtx_t(*pj_get_default_ctx()); } /************************************************************************/ @@ -145,8 +150,7 @@ projCtx pj_ctx_alloc() void pj_ctx_free( projCtx ctx ) { - proj_context_delete_cpp_context( ctx->cpp_context ); - pj_dealloc( ctx ); + delete ctx; } /************************************************************************/ @@ -210,7 +214,7 @@ void pj_ctx_set_app_data( projCtx ctx, void *new_app_data ) { if (nullptr==ctx) return; - ctx->app_data = new_app_data; + ctx->logger_app_data = new_app_data; } /************************************************************************/ @@ -222,7 +226,7 @@ void *pj_ctx_get_app_data( projCtx ctx ) { if (nullptr==ctx) return nullptr; - return ctx->app_data; + return ctx->logger_app_data; } /************************************************************************/ diff --git a/src/internal.cpp b/src/internal.cpp index f774cad6..fbc7c9a1 100644 --- a/src/internal.cpp +++ b/src/internal.cpp @@ -449,7 +449,7 @@ void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION logf) { pj_get_default_ctx (); if (nullptr==ctx) return; - ctx->app_data = app_data; + ctx->logger_app_data = app_data; if (nullptr!=logf) ctx->logger = logf; } diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 5717a76a..d13c33c7 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -74,7 +74,7 @@ static void PROJ_NO_INLINE proj_log_error(PJ_CONTEXT *ctx, const char *function, std::string msg(function); msg += ": "; msg += text; - ctx->logger(ctx->app_data, PJ_LOG_ERROR, msg.c_str()); + ctx->logger(ctx->logger_app_data, PJ_LOG_ERROR, msg.c_str()); } // --------------------------------------------------------------------------- @@ -84,7 +84,7 @@ static void PROJ_NO_INLINE proj_log_debug(PJ_CONTEXT *ctx, const char *function, std::string msg(function); msg += ": "; msg += text; - ctx->logger(ctx->app_data, PJ_LOG_DEBUG, msg.c_str()); + ctx->logger(ctx->logger_app_data, PJ_LOG_DEBUG, msg.c_str()); } // --------------------------------------------------------------------------- diff --git a/src/log.cpp b/src/log.cpp index 4c15772b..3cc10cfd 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -74,7 +74,7 @@ void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args ) /* we should use vsnprintf where available once we add configure detect.*/ vsprintf( msg_buf, fmt, args ); - ctx->logger( ctx->app_data, level, msg_buf ); + ctx->logger( ctx->logger_app_data, level, msg_buf ); free( msg_buf ); } diff --git a/src/proj_internal.h b/src/proj_internal.h index 63e10407..31365bce 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -644,14 +644,22 @@ struct projCppContext; /* proj thread context */ struct projCtx_t { - int last_errno; - int debug_level; - void (*logger)(void *, int, const char *); - void *app_data; - struct projFileAPI_t *fileapi; - struct projCppContext* cpp_context; /* internal context for C++ code */ - int use_proj4_init_rules; /* -1 = unknown, 0 = no, 1 = yes */ - int epsg_file_exists; /* -1 = unknown, 0 = no, 1 = yes */ + int last_errno = 0; + int debug_level = 0; + void (*logger)(void *, int, const char *) = nullptr; + void *logger_app_data = nullptr; + struct projFileAPI_t *fileapi = nullptr; + struct projCppContext* cpp_context = nullptr; /* internal context for C++ code */ + int use_proj4_init_rules = -1; /* -1 = unknown, 0 = no, 1 = yes */ + int epsg_file_exists = -1; /* -1 = unknown, 0 = no, 1 = yes */ + + projCtx_t() = default; + projCtx_t(const projCtx_t&); + ~projCtx_t(); + + projCtx_t& operator= (const projCtx_t&) = delete; + + static projCtx_t createDefault(); }; /* Generate pj_list external or make list from include file */ |
