Skip to content

Commit

Permalink
Convert VSIMemFile to shared_ptr (OSGeo#4184) (fixes OSGeo#4180)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmomtchev authored Aug 9, 2021
1 parent b46267a commit 60fbb33
Showing 1 changed file with 19 additions and 43 deletions.
62 changes: 19 additions & 43 deletions gdal/port/cpl_vsi_mem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <map>
#include <string>
#include <utility>
#include <memory>

#include "cpl_atomic_ops.h"
#include "cpl_conv.h"
Expand Down Expand Up @@ -96,7 +97,6 @@ class VSIMemFile

public:
CPLString osFilename{};
volatile int nRefCount = 0;

bool bIsDirectory = false;

Expand Down Expand Up @@ -125,7 +125,7 @@ class VSIMemHandle final : public VSIVirtualHandle
CPL_DISALLOW_COPY_ASSIGN(VSIMemHandle)

public:
VSIMemFile *poFile = nullptr;
std::shared_ptr<VSIMemFile> poFile = nullptr;
vsi_l_offset m_nOffset = 0;
bool bUpdate = false;
bool bEOF = false;
Expand Down Expand Up @@ -156,7 +156,7 @@ class VSIMemFilesystemHandler final : public VSIFilesystemHandler
CPL_DISALLOW_COPY_ASSIGN(VSIMemFilesystemHandler)

public:
std::map<CPLString, VSIMemFile*> oFileList{};
std::map<CPLString, std::shared_ptr<VSIMemFile> > oFileList{};
CPLMutex *hMutex = nullptr;

VSIMemFilesystemHandler() = default;
Expand Down Expand Up @@ -205,13 +205,7 @@ VSIMemFile::VSIMemFile()
/************************************************************************/

VSIMemFile::~VSIMemFile()

{
if( nRefCount != 0 )
CPLError( CE_Warning, CPLE_AppDefined,
"Memory file %s deleted with %d references.",
osFilename.c_str(), nRefCount );

if( bOwnData && pabyData )
CPLFree( pabyData );
}
Expand Down Expand Up @@ -306,11 +300,8 @@ int VSIMemHandle::Close()
{
#ifdef DEBUG_VERBOSE
CPLDebug("VSIMEM", "Closing handle %p on %s: ref_count=%d (before)",
this, poFile->osFilename.c_str(), poFile->nRefCount);
this, poFile->osFilename.c_str(), poFile.use_count());
#endif
if( CPLAtomicDec(&(poFile->nRefCount)) == 0 )
delete poFile;

poFile = nullptr;
}

Expand Down Expand Up @@ -491,11 +482,7 @@ int VSIMemHandle::Truncate( vsi_l_offset nNewSize )
VSIMemFilesystemHandler::~VSIMemFilesystemHandler()

{
for( const auto &iter : oFileList )
{
CPLAtomicDec(&iter.second->nRefCount);
delete iter.second;
}
oFileList.clear();

if( hMutex != nullptr )
CPLDestroyMutex( hMutex );
Expand Down Expand Up @@ -529,7 +516,7 @@ VSIMemFilesystemHandler::Open( const char *pszFilename,
/* -------------------------------------------------------------------- */
/* Get the filename we are opening, create if needed. */
/* -------------------------------------------------------------------- */
VSIMemFile *poFile = nullptr;
std::shared_ptr<VSIMemFile> poFile = nullptr;
if( oFileList.find(osFilename) != oFileList.end() )
poFile = oFileList[osFilename];

Expand All @@ -549,13 +536,12 @@ VSIMemFilesystemHandler::Open( const char *pszFilename,
// Create.
if( poFile == nullptr )
{
poFile = new VSIMemFile;
poFile = std::make_shared<VSIMemFile>();
poFile->osFilename = osFilename;
oFileList[poFile->osFilename] = poFile;
CPLAtomicInc(&(poFile->nRefCount)); // For file list.
#ifdef DEBUG_VERBOSE
CPLDebug("VSIMEM", "Creating file %s: ref_count=%d",
pszFilename, poFile->nRefCount);
pszFilename, poFile.use_count());
#endif
poFile->nMaxLength = nMaxLength;
}
Expand Down Expand Up @@ -585,10 +571,9 @@ VSIMemFilesystemHandler::Open( const char *pszFilename,
strstr(pszAccess, "+") ||
strstr(pszAccess, "a");

CPLAtomicInc(&(poFile->nRefCount));
#ifdef DEBUG_VERBOSE
CPLDebug("VSIMEM", "Opening handle %p on %s: ref_count=%d",
poHandle, pszFilename, poFile->nRefCount);
poHandle, pszFilename, poFile.use_count());
#endif
if( strstr(pszAccess, "a") )
poHandle->m_nOffset = poFile->nLength;
Expand Down Expand Up @@ -624,7 +609,7 @@ int VSIMemFilesystemHandler::Stat( const char * pszFilename,
return -1;
}

VSIMemFile *poFile = oFileList[osFilename];
std::shared_ptr<VSIMemFile> poFile = oFileList[osFilename];

memset( pStatBuf, 0, sizeof(VSIStatBufL) );

Expand Down Expand Up @@ -669,14 +654,10 @@ int VSIMemFilesystemHandler::Unlink_unlocked( const char * pszFilename )
return -1;
}

VSIMemFile *poFile = oFileList[osFilename];
#ifdef DEBUG_VERBOSE
CPLDebug("VSIMEM", "Unlink %s: ref_count=%d (before)",
pszFilename, poFile->nRefCount);
std::shared_ptr<VSIMemFile> poFile = oFileList[osFilename];
CPLDebug("VSIMEM", "Unlink %s: ref_count=%d (before)", pszFilename, poFile.use_count());
#endif
if( CPLAtomicDec(&(poFile->nRefCount)) == 0 )
delete poFile;

oFileList.erase( oFileList.find(osFilename) );

return 0;
Expand All @@ -700,15 +681,13 @@ int VSIMemFilesystemHandler::Mkdir( const char * pszPathname,
return -1;
}

VSIMemFile *poFile = new VSIMemFile;

std::shared_ptr<VSIMemFile> poFile = std::make_shared<VSIMemFile>();
poFile->osFilename = osPathname;
poFile->bIsDirectory = true;
oFileList[osPathname] = poFile;
CPLAtomicInc(&(poFile->nRefCount)); // Referenced by file list.
#ifdef DEBUG_VERBOSE
CPLDebug("VSIMEM", "Mkdir on %s: ref_count=%d",
pszPathname, poFile->nRefCount);
pszPathname, poFile.use_count());
#endif
return 0;
}
Expand Down Expand Up @@ -801,7 +780,7 @@ int VSIMemFilesystemHandler::Rename( const char *pszOldPath,
return -1;
}

std::map<CPLString, VSIMemFile*>::iterator it = oFileList.find(osOldPath);
std::map<CPLString, std::shared_ptr<VSIMemFile> >::iterator it = oFileList.find(osOldPath);
while( it != oFileList.end() && it->first.ifind(osOldPath) == 0 )
{
const CPLString osRemainder = it->first.substr(osOldPath.size());
Expand Down Expand Up @@ -953,7 +932,7 @@ VSILFILE *VSIFileFromMemBuffer( const char *pszFilename,
if( osFilename.empty() )
return nullptr;

VSIMemFile *poFile = new VSIMemFile;
std::shared_ptr<VSIMemFile> poFile = std::make_shared<VSIMemFile>();

poFile->osFilename = osFilename;
poFile->bOwnData = CPL_TO_BOOL(bTakeOwnership);
Expand All @@ -965,10 +944,9 @@ VSILFILE *VSIFileFromMemBuffer( const char *pszFilename,
CPLMutexHolder oHolder( &poHandler->hMutex );
poHandler->Unlink_unlocked(osFilename);
poHandler->oFileList[poFile->osFilename] = poFile;
CPLAtomicInc(&(poFile->nRefCount));
#ifdef DEBUG_VERBOSE
CPLDebug("VSIMEM", "VSIFileFromMemBuffer() %s: ref_count=%d (after)",
poFile->osFilename.c_str(), poFile->nRefCount);
poFile->osFilename.c_str(), poFile->use_count());
#endif
}

Expand Down Expand Up @@ -1016,7 +994,7 @@ GByte *VSIGetMemFileBuffer( const char *pszFilename,
if( poHandler->oFileList.find(osFilename) == poHandler->oFileList.end() )
return nullptr;

VSIMemFile *poFile = poHandler->oFileList[osFilename];
std::shared_ptr<VSIMemFile> poFile = poHandler->oFileList[osFilename];
GByte *pabyData = poFile->pabyData;
if( pnDataLength != nullptr )
*pnDataLength = poFile->nLength;
Expand All @@ -1032,13 +1010,11 @@ GByte *VSIGetMemFileBuffer( const char *pszFilename,
poHandler->oFileList.erase( poHandler->oFileList.find(osFilename) );
#ifdef DEBUG_VERBOSE
CPLDebug("VSIMEM", "VSIGetMemFileBuffer() %s: ref_count=%d (before)",
poFile->osFilename.c_str(), poFile->nRefCount);
poFile->osFilename.c_str(), poFile.use_count());
#endif
poFile->pabyData = nullptr;
poFile->nLength = 0;
poFile->nAllocLength = 0;
if (CPLAtomicDec(&(poFile->nRefCount)) == 0)
delete poFile;
}

return pabyData;
Expand Down

0 comments on commit 60fbb33

Please sign in to comment.