From 37fc279c8f5742fb67f52d181d7c8da8a4a166c4 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Thu, 11 Dec 2003 05:32:35 +0000 Subject: [PATCH] refcount drivers --- stepmania/src/RageFile.cpp | 2 +- stepmania/src/RageFileManager.cpp | 43 +++++++++++++++++++++++++++++-- stepmania/src/RageFileManager.h | 1 + 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/stepmania/src/RageFile.cpp b/stepmania/src/RageFile.cpp index cf9c2c677a..572f79bacf 100644 --- a/stepmania/src/RageFile.cpp +++ b/stepmania/src/RageFile.cpp @@ -115,7 +115,7 @@ bool RageFile::Open( const CString& path, RageFile::OpenMode mode ) void RageFile::Close() { - delete m_File; + FILEMAN->Close( m_File ); m_File = NULL; } diff --git a/stepmania/src/RageFileManager.cpp b/stepmania/src/RageFileManager.cpp index 202dfab547..bb4ed4f5cf 100644 --- a/stepmania/src/RageFileManager.cpp +++ b/stepmania/src/RageFileManager.cpp @@ -29,6 +29,9 @@ public: }; static RageFileDriverMountpoints *g_Mountpoints = NULL; +typedef map< const RageFileObj *, RageFileDriver * > FileReferences; +static FileReferences g_Refs; + struct LoadedDriver { /* A loaded driver may have a base path, which modifies the path we @@ -39,6 +42,7 @@ struct LoadedDriver RageFileDriver *driver; CString MountPoint; + LoadedDriver() { driver = NULL; } CString GetPath( CString path ); }; @@ -283,6 +287,25 @@ static bool SortBySecond( const pair &a, const pair &b ) return a.second < b.second; } +void AddReference( const RageFileObj *obj, RageFileDriver *driver ) +{ + pair< const RageFileObj *, RageFileDriver * > ref; + ref.first = obj; + ref.second = driver; + + /* map::insert returns an iterator (which we discard) and a bool, indicating whether + * this is a new entry. This should always be new. */ + const pair< FileReferences::iterator, bool > ret = g_Refs.insert( ref ); + RAGE_ASSERT_M( ret.second, ssprintf( "RemoveReference: Duplicate reference (%s)", obj->GetDisplayPath().c_str() ) ); +} + +void RemoveReference( const RageFileObj *obj ) +{ + FileReferences::iterator it = g_Refs.find( obj ); + RAGE_ASSERT_M( it != g_Refs.end(), ssprintf( "RemoveReference: Missing reference (%s)", obj->GetDisplayPath().c_str() ) ); + g_Refs.erase( it ); +} + /* Used only by RageFile: */ RageFileObj *RageFileManager::Open( const CString &sPath, RageFile::OpenMode mode, RageFile &p, int &err ) { @@ -295,13 +318,17 @@ RageFileObj *RageFileManager::Open( const CString &sPath, RageFile::OpenMode mod for( unsigned i = 0; i < g_Drivers.size(); ++i ) { - const CString path = g_Drivers[i].GetPath( sPath ); + LoadedDriver &ld = g_Drivers[i]; + const CString path = ld.GetPath( sPath ); if( path.size() == 0 ) continue; int error; - RageFileObj *ret = g_Drivers[i].driver->Open( path, mode, p, error ); + RageFileObj *ret = ld.driver->Open( path, mode, p, error ); if( ret ) + { + AddReference( ret, ld.driver ); return ret; + } /* ENOENT (File not found) is low-priority: if some other error * was reported, return that instead. */ @@ -367,12 +394,24 @@ RageFileObj *RageFileManager::OpenForWriting( const CString &sPath, RageFile::Op RageFileObj *ret = ld.driver->Open( path, mode, p, error ); if( ret ) + { + AddReference( ret, ld.driver ); return ret; + } } err = error; return NULL; } +void RageFileManager::Close( RageFileObj *obj ) +{ + if( obj == NULL ) + return; + + RemoveReference( obj ); + delete obj; +} + bool RageFileManager::IsAFile( const CString &sPath ) { return GetFileType(sPath) == TYPE_FILE; } bool RageFileManager::IsADirectory( const CString &sPath ) { return GetFileType(sPath) == TYPE_DIR; } bool RageFileManager::DoesFileExist( const CString &sPath ) { return GetFileType(sPath) != TYPE_NONE; } diff --git a/stepmania/src/RageFileManager.h b/stepmania/src/RageFileManager.h index 27e33d41bd..f9c9676176 100644 --- a/stepmania/src/RageFileManager.h +++ b/stepmania/src/RageFileManager.h @@ -30,6 +30,7 @@ public: /* Used only by RageFile: */ RageFileObj *Open( const CString &sPath, RageFile::OpenMode mode, RageFile &p, int &err ); + void Close( RageFileObj *obj ); private: RageFileObj *OpenForWriting( const CString &sPath, RageFile::OpenMode mode, RageFile &p, int &err );