Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 7.0] hgridshift/vgridshift: defer grid opening when grid has already been opened #2132

Merged
merged 2 commits into from
Apr 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/malloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
3 changes: 3 additions & 0 deletions src/proj_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,9 @@ std::string PROJ_DLL pj_context_get_user_writable_directory(PJ_CONTEXT *ctx, boo
void PROJ_DLL pj_context_set_user_writable_directory(PJ_CONTEXT* ctx, const std::string& path);
std::string PROJ_DLL pj_get_relative_share_proj(PJ_CONTEXT *ctx);

void pj_clear_hgridshift_knowngrids_cache();
void pj_clear_vgridshift_knowngrids_cache();

/* classic public API */
#include "proj_api.h"

Expand Down
51 changes: 44 additions & 7 deletions src/transformations/hgridshift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
53 changes: 47 additions & 6 deletions src/transformations/vgridshift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
}

Expand All @@ -214,3 +249,9 @@ PJ *TRANSFORMATION(vgridshift,0) {

return P;
}

void pj_clear_vgridshift_knowngrids_cache() {
gMutex.lock();
gKnownGrids.clear();
gMutex.unlock();
}
7 changes: 7 additions & 0 deletions test/unit/test_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -174,6 +180,7 @@ TEST(networking, basic) {
ASSERT_EQ(P, nullptr);
#endif
proj_context_destroy(ctx);
proj_cleanup();
}

// ---------------------------------------------------------------------------
Expand Down