Skip to content

Commit

Permalink
Merge pull request #8616 from rouault/fix_8599
Browse files Browse the repository at this point in the history
GDALOpen(): avoid error messages in OF_SHARED mode and with OVERVIEW_LEVEL option (fixes #8599)
  • Loading branch information
rouault authored Oct 27, 2023
2 parents 03f4d17 + 666677b commit 941f1a5
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 28 deletions.
23 changes: 23 additions & 0 deletions autotest/cpp/test_gdal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3420,6 +3420,7 @@ TEST_F(test_gdal, jpegxl_jpeg_compatible_ReadCompressedData)
// Test GDAL_OF_SHARED flag and open options
TEST_F(test_gdal, open_shared_open_options)
{
CPLErrorReset();
const char *const apszOpenOptions[] = {"OVERVIEW_LEVEL=NONE", nullptr};
{
GDALDataset *poDS1 =
Expand All @@ -3428,6 +3429,7 @@ TEST_F(test_gdal, open_shared_open_options)
GDALDataset *poDS2 =
GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
nullptr, apszOpenOptions);
EXPECT_EQ(CPLGetLastErrorType(), CE_None);
EXPECT_NE(poDS1, nullptr);
EXPECT_NE(poDS2, nullptr);
EXPECT_EQ(poDS1, poDS2);
Expand All @@ -3443,6 +3445,7 @@ TEST_F(test_gdal, open_shared_open_options)
GDALDataset *poDS3 =
GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
nullptr, apszOpenOptions);
EXPECT_EQ(CPLGetLastErrorType(), CE_None);
EXPECT_NE(poDS1, nullptr);
EXPECT_NE(poDS2, nullptr);
EXPECT_NE(poDS3, nullptr);
Expand All @@ -3460,12 +3463,32 @@ TEST_F(test_gdal, open_shared_open_options)
GDALDataset *poDS2 =
GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
nullptr, apszOpenOptions);
EXPECT_EQ(CPLGetLastErrorType(), CE_None);
EXPECT_NE(poDS1, nullptr);
EXPECT_NE(poDS2, nullptr);
EXPECT_EQ(poDS1, poDS2);
GDALClose(poDS1);
GDALClose(poDS2);
}
{
GDALDataset *poDS1 = GDALDataset::Open(
GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED, nullptr, nullptr);
GDALDataset *poDS2 =
GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
nullptr, apszOpenOptions);
GDALDataset *poDS3 =
GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
nullptr, apszOpenOptions);
EXPECT_EQ(CPLGetLastErrorType(), CE_None);
EXPECT_NE(poDS1, nullptr);
EXPECT_NE(poDS2, nullptr);
EXPECT_NE(poDS3, nullptr);
EXPECT_NE(poDS1, poDS2);
EXPECT_EQ(poDS2, poDS3);
GDALClose(poDS1);
GDALClose(poDS2);
GDALClose(poDS3);
}
}

} // namespace
72 changes: 44 additions & 28 deletions gcore/gdaldataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1621,7 +1621,7 @@ void GDALDataset::MarkAsShared()
}

/************************************************************************/
/* MarkAsShared() */
/* MarkSuppressOnClose() */
/************************************************************************/

/** Set that the dataset must be deleted on close. */
Expand Down Expand Up @@ -3332,6 +3332,44 @@ GDALDatasetH CPL_STDCALL GDALOpen(const char *pszFilename, GDALAccess eAccess)
return hDataset;
}

/************************************************************************/
/* GetSharedDS() */
/************************************************************************/

static GDALDataset *GetSharedDS(const char *pszFilename,
unsigned int nOpenFlags,
const char *const *papszOpenOptions)
{
CPLMutexHolderD(&hDLMutex);

if (phSharedDatasetSet != nullptr)
{
const GIntBig nThisPID = GDALGetResponsiblePIDForCurrentThread();
SharedDatasetCtxt sStruct;

sStruct.nPID = nThisPID;
sStruct.pszDescription = const_cast<char *>(pszFilename);
sStruct.nOpenFlags = nOpenFlags & ~GDAL_OF_SHARED;
std::string osConcatenatedOpenOptions =
GDALSharedDatasetConcatenateOpenOptions(papszOpenOptions);
sStruct.pszConcatenatedOpenOptions = &osConcatenatedOpenOptions[0];
sStruct.poDS = nullptr;
SharedDatasetCtxt *psStruct = static_cast<SharedDatasetCtxt *>(
CPLHashSetLookup(phSharedDatasetSet, &sStruct));
if (psStruct == nullptr && (nOpenFlags & GDAL_OF_UPDATE) == 0)
{
sStruct.nOpenFlags |= GDAL_OF_UPDATE;
psStruct = static_cast<SharedDatasetCtxt *>(
CPLHashSetLookup(phSharedDatasetSet, &sStruct));
}
if (psStruct)
{
return psStruct->poDS;
}
}
return nullptr;
}

/************************************************************************/
/* GDALOpenEx() */
/************************************************************************/
Expand Down Expand Up @@ -3451,33 +3489,12 @@ GDALDatasetH CPL_STDCALL GDALOpenEx(const char *pszFilename,
return nullptr;
}

CPLMutexHolderD(&hDLMutex);

if (phSharedDatasetSet != nullptr)
auto poSharedDS =
GetSharedDS(pszFilename, nOpenFlags, papszOpenOptions);
if (poSharedDS)
{
const GIntBig nThisPID = GDALGetResponsiblePIDForCurrentThread();
SharedDatasetCtxt sStruct;

sStruct.nPID = nThisPID;
sStruct.pszDescription = const_cast<char *>(pszFilename);
sStruct.nOpenFlags = nOpenFlags & ~GDAL_OF_SHARED;
std::string osConcatenatedOpenOptions =
GDALSharedDatasetConcatenateOpenOptions(papszOpenOptions);
sStruct.pszConcatenatedOpenOptions = &osConcatenatedOpenOptions[0];
sStruct.poDS = nullptr;
SharedDatasetCtxt *psStruct = static_cast<SharedDatasetCtxt *>(
CPLHashSetLookup(phSharedDatasetSet, &sStruct));
if (psStruct == nullptr && (nOpenFlags & GDAL_OF_UPDATE) == 0)
{
sStruct.nOpenFlags |= GDAL_OF_UPDATE;
psStruct = static_cast<SharedDatasetCtxt *>(
CPLHashSetLookup(phSharedDatasetSet, &sStruct));
}
if (psStruct)
{
psStruct->poDS->Reference();
return psStruct->poDS;
}
poSharedDS->Reference();
return poSharedDS;
}
}

Expand Down Expand Up @@ -3697,7 +3714,6 @@ GDALDatasetH CPL_STDCALL GDALOpenEx(const char *pszFilename,
poDS->papszOpenOptions = CSLDuplicate(papszOpenOptions);
poDS->papszOpenOptions = CSLSetNameValue(
poDS->papszOpenOptions, "OVERVIEW_LEVEL", nullptr);
poDS->MarkAsShared();
}
}
poDS->ReleaseRef();
Expand Down

0 comments on commit 941f1a5

Please sign in to comment.