[processing] Use a list of previous temporary folders, so that we can defer

cleanup of ALL of them until session end
This commit is contained in:
Nyall Dawson 2020-01-28 10:16:11 +10:00
parent 9e4a53b9c4
commit a2f37ccc5d

View File

@ -746,33 +746,35 @@ QVariant QgsProcessingUtils::generateIteratingDestination( const QVariant &input
QString QgsProcessingUtils::tempFolder() QString QgsProcessingUtils::tempFolder()
{ {
static std::unique_ptr< QTemporaryDir > sTempFolder; // we maintain a list of temporary folders -- this allows us to append additional
// folders when a setting change causes the base temp folder to change, while deferring
// cleanup of ALL these temp folders until session end (we can't cleanup older folders immediately,
// because we don't know whether they have data in them which is still wanted)
static std::vector< std::unique_ptr< QTemporaryDir > > sTempFolders;
static QString sFolder; static QString sFolder;
static QMutex sMutex; static QMutex sMutex;
QMutexLocker locker( &sMutex ); QMutexLocker locker( &sMutex );
const QString basePath = QgsSettings().value( QStringLiteral( "Processing/Configuration/TEMP_PATH2" ) ).toString(); const QString basePath = QgsSettings().value( QStringLiteral( "Processing/Configuration/TEMP_PATH2" ) ).toString();
if ( basePath.isEmpty() ) if ( basePath.isEmpty() )
{ {
// default setting -- automatically create a temp folder. In this case, we use QTemporaryDir so // default setting -- automatically create a temp folder
// that the folder is automatically deleted when QGIS is closed if ( sTempFolders.empty() )
if ( !sTempFolder )
{ {
const QString templatePath = QStringLiteral( "%1/processing_XXXXXX" ).arg( QDir::tempPath() ); const QString templatePath = QStringLiteral( "%1/processing_XXXXXX" ).arg( QDir::tempPath() );
sTempFolder = qgis::make_unique< QTemporaryDir >( templatePath ); std::unique_ptr< QTemporaryDir > tempFolder = qgis::make_unique< QTemporaryDir >( templatePath );
sFolder = sTempFolder->path(); sFolder = tempFolder->path();
sTempFolders.emplace_back( std::move( tempFolder ) );
} }
} }
else if ( sFolder.isEmpty() || !sFolder.startsWith( basePath ) || !sTempFolder ) else if ( sFolder.isEmpty() || !sFolder.startsWith( basePath ) || sTempFolders.empty() )
{ {
if ( !QDir().exists( basePath ) ) if ( !QDir().exists( basePath ) )
QDir().mkpath( basePath ); QDir().mkpath( basePath );
const QString templatePath = QStringLiteral( "%1/processing_XXXXXX" ).arg( basePath ); const QString templatePath = QStringLiteral( "%1/processing_XXXXXX" ).arg( basePath );
// leak the previous folder -- we don't want it to be cleaned up, we don't know what was in it that may still std::unique_ptr< QTemporaryDir > tempFolder = qgis::make_unique< QTemporaryDir >( templatePath );
// be required for this session! sFolder = tempFolder->path();
sTempFolder.release(); sTempFolders.emplace_back( std::move( tempFolder ) );
sTempFolder = qgis::make_unique< QTemporaryDir >( templatePath );
sFolder = sTempFolder->path();
} }
return sFolder; return sFolder;
} }