Opened 11 years ago
Closed 10 years ago
#5101 closed defect (worksforme)
GDALDataset::GetProjectionRef() blocking
Reported by: | Kosta | Owned by: | warmerdam |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | GDAL_Raster | Version: | 1.9.2 |
Severity: | normal | Keywords: | |
Cc: |
Description (last modified by )
It seems that the call to GDALDataset::GetProjectionRef() can sometimes block when used in a multi-threaded environment and used on a dataset opened twice and accessed from two different threads for certain datasets. Sample program to reproduce the behavior (sorry for the usage of boost threads):
const char RASTER_FILE[] = "D:/test.tif"; GDALDataset* const ds1 = static_cast<GDALDataset*>(GDALOpen(RASTER_FILE, GA_ReadOnly)); GDALDataset* const ds2 = static_cast<GDALDataset*>(GDALOpen(RASTER_FILE, GA_ReadOnly)); boost::thread thread1([&]() { std::cout << "#1: start calling GetProjectionRef() on thread #" << boost::this_thread::get_id() << std::endl; ds1->GetProjectionRef(); std::cout << "#1: GetProjectionRef(): done" << std::endl; boost::this_thread::sleep_for(boost::chrono::seconds(30)); std::cout << "#1: deleting DS" << std::endl; delete ds1; std::cout << "#1: DS deleted" << std::endl; }); boost::thread thread2([&]() { boost::this_thread::sleep_for(boost::chrono::seconds(10)); std::cout << "#2: start calling GetProjectionRef() on thread #" << boost::this_thread::get_id() << std::endl; ds2->GetProjectionRef(); std::cout << "#2: GetProjectionRef(): done" << std::endl; std::cout << "#2: deleting DS" << std::endl; delete ds2; std::cout << "#2: DS deleted" << std::endl; }); thread1.join(); thread2.join();
The call to GetProjectionRef() on the 2nd threads blocks until the 1st datasource object gets deleted by the 1st thread. You can observe the same behavior if you use a copy of the attached GeoTiff and open both datasets from the 2 different files. Maybe that is related to the not-found EPSG code used by the GeoTiff, which then holds on to an internal lock/mutex?
This has been observed on Windows and I haven't checked this with GDAL 1.10 yet...
Attachments (1)
Change History (5)
by , 11 years ago
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Description: | modified (diff) |
---|
comment:3 by , 11 years ago
I don't reproduce with GDAL 1.10. Here's my source (adapted with just GDAL stuff, but CPLCreateJoinableThread() is a new GDAL 1.10 stuff) if you want to test it :
#include <gdal_priv.h> #include <cpl_multiproc.h> #include <iostream> void main1(void *arg) { GDALDataset* ds1 = (GDALDataset*)arg; std::cout << "#1: start calling GetProjectionRef() on thread #1" << std::endl; ds1->GetProjectionRef(); std::cout << "#1: GetProjectionRef(): done. Sleeping for 10" << std::endl; CPLSleep(10); std::cout << "#1: deleting DS" << std::endl; delete ds1; std::cout << "#1: DS deleted" << std::endl; } void main2(void *arg) { GDALDataset* ds2 = (GDALDataset*)arg; //std::cout << "#2: before sleep" << std::endl; CPLSleep(1); std::cout << "#2: start calling GetProjectionRef() on thread #2" << std::endl; ds2->GetProjectionRef(); std::cout << "#2: GetProjectionRef(): done" << std::endl; std::cout << "#2: deleting DS" << std::endl; delete ds2; std::cout << "#2: DS deleted" << std::endl; } int main(int argc, char* argv[]) { GDALAllRegister(); const char RASTER_FILE[] = "test.tif"; GDALDataset* const ds1 = static_cast<GDALDataset*>(GDALOpen(RASTER_FILE, GA_ReadOnly)); GDALDataset* const ds2 = static_cast<GDALDataset*>(GDALOpen(RASTER_FILE, GA_ReadOnly)); void* t1 = CPLCreateJoinableThread( main1, ds1 ); void* t2 = CPLCreateJoinableThread( main2, ds2 ); CPLJoinThread(t1); CPLJoinThread(t2); return 0; }
The output is :
ERROR 6: EPSG PCS/GCS code 5100 not found in EPSG support files. Is this a vali d EPSG coordinate system? #1: GetProjectionRef(): done. Sleeping for 10 #2: start calling GetProjectionRef() on thread #2 ERROR 6: EPSG PCS/GCS code 5100 not found in EPSG support files. Is this a vali d EPSG coordinate system? #2: GetProjectionRef(): done #2: deleting DS #2: DS deleted #1: deleting DS #1: DS deleted
comment:4 by , 10 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
Closed due to lack of feedback from reporter. Reopen if you can provide more elements
BTW, it also doesn't matter if I open the 2 datasets within the 2 threads; I just avoided that in the example to make it a bit shorter...