aboutsummaryrefslogtreecommitdiff
path: root/test/unit
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-06-02 23:11:31 +0200
committerEven Rouault <even.rouault@spatialys.com>2021-06-03 11:29:16 +0200
commit1c80b05e007340ed213e7f492b73631810e8aec4 (patch)
treec4c3db5b4f669926b3ea15e56d6c139f70e308bb /test/unit
parent9ce2d6fc0e1d7591d0d588a16ab6589910092cfc (diff)
downloadPROJ-1c80b05e007340ed213e7f492b73631810e8aec4.tar.gz
PROJ-1c80b05e007340ed213e7f492b73631810e8aec4.zip
Check that database connection sharing properly works
Diffstat (limited to 'test/unit')
-rw-r--r--test/unit/test_c_api.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index d9e731a7..90641bd1 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -47,6 +47,10 @@
#include <sqlite3.h>
+#ifndef __MINGW32__
+#include <thread>
+#endif
+
using namespace osgeo::proj::common;
using namespace osgeo::proj::crs;
using namespace osgeo::proj::cs;
@@ -5544,4 +5548,72 @@ TEST_F(CApi, proj_get_geoid_models_from_database) {
EXPECT_FALSE(findInList(list, "OSGM15"));
}
+// ---------------------------------------------------------------------------
+
+#if !defined(_WIN32)
+TEST_F(CApi, open_plenty_of_contexts) {
+ // Test that we only consume 1 file handle for the connection to the
+ // database
+ std::vector<FILE *> dummyFilePointers;
+ std::vector<PJ_CONTEXT *> ctxts;
+ // 1024 is the number of file descriptors that can be opened simultaneously
+ // by a Linux process (by default)
+ for (int i = 0; i < 1024 - 50; i++) {
+ FILE *f = fopen("/dev/null", "rb");
+ ASSERT_TRUE(f != nullptr);
+ dummyFilePointers.push_back(f);
+ }
+ for (int i = 0; i < 100; i++) {
+ PJ_CONTEXT *ctxt = proj_context_create();
+ ASSERT_TRUE(ctxt != nullptr);
+ auto obj = proj_create(ctxt, "EPSG:4326");
+ ObjectKeeper keeper(obj);
+ EXPECT_NE(obj, nullptr);
+ ctxts.push_back(ctxt);
+ }
+ for (PJ_CONTEXT *ctxt : ctxts) {
+ proj_context_destroy(ctxt);
+ }
+ for (FILE *f : dummyFilePointers) {
+ fclose(f);
+ }
+ proj_cleanup();
+}
+#endif // !defined(_WIN32)
+
+// ---------------------------------------------------------------------------
+
+#ifndef __MINGW32__
+// We need std::thread support
+
+TEST_F(CApi, concurrent_context) {
+ // Test that concurrent access to the database is thread safe.
+ std::vector<std::thread> threads;
+ for (int i = 0; i < 4; i++) {
+ threads.emplace_back(std::thread([] {
+ for (int j = 0; j < 60; j++) {
+ PJ_CONTEXT *ctxt = proj_context_create();
+ {
+ auto obj = proj_create(ctxt, "EPSG:4326");
+ ObjectKeeper keeper(obj);
+ EXPECT_NE(obj, nullptr);
+ }
+ {
+ auto obj = proj_create(
+ ctxt, ("EPSG:" + std::to_string(32600 + j)).c_str());
+ ObjectKeeper keeper(obj);
+ EXPECT_NE(obj, nullptr);
+ }
+ proj_context_destroy(ctxt);
+ }
+ }));
+ }
+ for (auto &t : threads) {
+ t.join();
+ }
+ proj_cleanup();
+}
+
+#endif // __MINGW32__
+
} // namespace