aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/malloc.cpp2
-rw-r--r--src/proj_internal.h3
-rw-r--r--src/transformations/hgridshift.cpp51
-rw-r--r--src/transformations/vgridshift.cpp53
-rw-r--r--test/unit/test_network.cpp7
5 files changed, 103 insertions, 13 deletions
diff --git a/src/malloc.cpp b/src/malloc.cpp
index 9ac28546..10ab2fad 100644
--- a/src/malloc.cpp
+++ b/src/malloc.cpp
@@ -264,4 +264,6 @@ void proj_cleanup() {
pj_clear_initcache();
pj_deallocate_grids();
FileManager::clearMemoryCache();
+ pj_clear_hgridshift_knowngrids_cache();
+ pj_clear_vgridshift_knowngrids_cache();
}
diff --git a/src/proj_internal.h b/src/proj_internal.h
index 4dc63e1d..a7c1ddc8 100644
--- a/src/proj_internal.h
+++ b/src/proj_internal.h
@@ -890,6 +890,9 @@ int pj_get_suggested_operation(PJ_CONTEXT *ctx,
const PJ_UNITS *pj_list_linear_units();
const PJ_UNITS *pj_list_angular_units();
+void pj_clear_hgridshift_knowngrids_cache();
+void pj_clear_vgridshift_knowngrids_cache();
+
/* classic public API */
#include "proj_api.h"
diff --git a/src/transformations/hgridshift.cpp b/src/transformations/hgridshift.cpp
index 122a7ab2..b28eaf48 100644
--- a/src/transformations/hgridshift.cpp
+++ b/src/transformations/hgridshift.cpp
@@ -12,6 +12,25 @@ PROJ_HEAD(hgridshift, "Horizontal grid shift");
using namespace NS_PROJ;
+#ifdef __MINGW32__
+// mingw32-win32 doesn't implement std::mutex
+namespace {
+class MyMutex {
+ public:
+ // cppcheck-suppress functionStatic
+ void lock() { pj_acquire_lock(); }
+ // cppcheck-suppress functionStatic
+ void unlock() { pj_release_lock(); }
+};
+}
+#else
+#include <mutex>
+#define MyMutex std::mutex
+#endif
+
+static MyMutex gMutex{};
+static std::set<std::string> gKnownGrids{};
+
namespace { // anonymous namespace
struct hgridshiftData {
double t_final = 0;
@@ -160,18 +179,36 @@ PJ *TRANSFORMATION(hgridshift,0) {
if (pj_param(P->ctx, P->params, "tt_epoch").i)
Q->t_epoch = pj_param (P->ctx, P->params, "dt_epoch").f;
-
if( P->ctx->defer_grid_opening ) {
Q->defer_grid_opening = true;
}
else {
- Q->grids = pj_hgrid_init(P, "grids");
- /* Was gridlist compiled properly? */
- if ( proj_errno(P) ) {
- proj_log_error(P, "hgridshift: could not find required grid(s).");
- return destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID);
+ const char *gridnames = pj_param(P->ctx, P->params, "sgrids").s;
+ gMutex.lock();
+ const bool isKnownGrid = gKnownGrids.find(gridnames) != gKnownGrids.end();
+ gMutex.unlock();
+ if( isKnownGrid ) {
+ Q->defer_grid_opening = true;
}
- }
+ else {
+ Q->grids = pj_hgrid_init(P, "grids");
+ /* Was gridlist compiled properly? */
+ if ( proj_errno(P) ) {
+ proj_log_error(P, "hgridshift: could not find required grid(s).");
+ return destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID);
+ }
+
+ gMutex.lock();
+ gKnownGrids.insert(gridnames);
+ gMutex.unlock();
+ }
+ }
return P;
}
+
+void pj_clear_hgridshift_knowngrids_cache() {
+ gMutex.lock();
+ gKnownGrids.clear();
+ gMutex.unlock();
+}
diff --git a/src/transformations/vgridshift.cpp b/src/transformations/vgridshift.cpp
index 121b795a..6ee8a6b0 100644
--- a/src/transformations/vgridshift.cpp
+++ b/src/transformations/vgridshift.cpp
@@ -12,6 +12,27 @@ PROJ_HEAD(vgridshift, "Vertical grid shift");
using namespace NS_PROJ;
+
+#ifdef __MINGW32__
+// mingw32-win32 doesn't implement std::mutex
+namespace {
+class MyMutex {
+ public:
+ // cppcheck-suppress functionStatic
+ void lock() { pj_acquire_lock(); }
+ // cppcheck-suppress functionStatic
+ void unlock() { pj_release_lock(); }
+};
+}
+#else
+#include <mutex>
+#define MyMutex std::mutex
+#endif
+
+static MyMutex gMutex{};
+static std::set<std::string> gKnownGrids{};
+
+
namespace { // anonymous namespace
struct vgridshiftData {
double t_final = 0;
@@ -192,13 +213,27 @@ PJ *TRANSFORMATION(vgridshift,0) {
Q->defer_grid_opening = true;
}
else {
- /* Build gridlist. P->vgridlist_geoid can be empty if +grids only ask for optional grids. */
- Q->grids = pj_vgrid_init(P, "grids");
+ const char *gridnames = pj_param(P->ctx, P->params, "sgrids").s;
+ gMutex.lock();
+ const bool isKnownGrid = gKnownGrids.find(gridnames) != gKnownGrids.end();
+ gMutex.unlock();
- /* Was gridlist compiled properly? */
- if ( proj_errno(P) ) {
- proj_log_error(P, "vgridshift: could not find required grid(s).");
- return destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID);
+ if( isKnownGrid ) {
+ Q->defer_grid_opening = true;
+ }
+ else {
+ /* Build gridlist. P->vgridlist_geoid can be empty if +grids only ask for optional grids. */
+ Q->grids = pj_vgrid_init(P, "grids");
+
+ /* Was gridlist compiled properly? */
+ if ( proj_errno(P) ) {
+ proj_log_error(P, "vgridshift: could not find required grid(s).");
+ return destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID);
+ }
+
+ gMutex.lock();
+ gKnownGrids.insert(gridnames);
+ gMutex.unlock();
}
}
@@ -214,3 +249,9 @@ PJ *TRANSFORMATION(vgridshift,0) {
return P;
}
+
+void pj_clear_vgridshift_knowngrids_cache() {
+ gMutex.lock();
+ gKnownGrids.clear();
+ gMutex.unlock();
+}
diff --git a/test/unit/test_network.cpp b/test/unit/test_network.cpp
index 429a7303..db3e987f 100644
--- a/test/unit/test_network.cpp
+++ b/test/unit/test_network.cpp
@@ -127,6 +127,8 @@ TEST(networking, basic) {
ASSERT_EQ(P, nullptr);
proj_context_destroy(ctx);
+ proj_cleanup();
+
#ifdef CURL_ENABLED
// enable through env variable
ctx = proj_context_create();
@@ -141,6 +143,8 @@ TEST(networking, basic) {
putenv(const_cast<char *>("PROJ_NETWORK="));
#endif
+ proj_cleanup();
+
// still disabled
ctx = proj_context_create();
proj_grid_cache_set_enable(ctx, false);
@@ -149,6 +153,8 @@ TEST(networking, basic) {
ASSERT_EQ(P, nullptr);
proj_context_destroy(ctx);
+ proj_cleanup();
+
// enable through API
ctx = proj_context_create();
proj_grid_cache_set_enable(ctx, false);
@@ -174,6 +180,7 @@ TEST(networking, basic) {
ASSERT_EQ(P, nullptr);
#endif
proj_context_destroy(ctx);
+ proj_cleanup();
}
// ---------------------------------------------------------------------------