mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-23 07:29:46 +02:00
Strong safety guarantee for removing file dependencies
This commit is contained in:
parent
7159966eb4
commit
f5fe9281e4
@ -116,6 +116,7 @@ unsigned long BlockFile::gBlockFileDestructionCount { 0 };
|
||||
BlockFile::~BlockFile()
|
||||
{
|
||||
if (!IsLocked() && mFileName.HasName())
|
||||
// PRL: what should be done if this fails?
|
||||
wxRemoveFile(mFileName.GetFullPath());
|
||||
|
||||
++gBlockFileDestructionCount;
|
||||
|
@ -81,16 +81,12 @@ static void GetAllSeqBlocks(AudacityProject *project,
|
||||
// tracks and replace each aliased block file with its replacement.
|
||||
// Note that this code respects reference-counting and thus the
|
||||
// process of making a project self-contained is actually undoable.
|
||||
static void ReplaceBlockFiles(AudacityProject *project,
|
||||
static void ReplaceBlockFiles(BlockPtrArray &blocks,
|
||||
ReplacedBlockFileHash &hash)
|
||||
// NOFAIL-GUARANTEE
|
||||
{
|
||||
//const auto &dirManager = project->GetDirManager();
|
||||
BlockPtrArray blocks;
|
||||
GetAllSeqBlocks(project, &blocks);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < (int)blocks.size(); i++) {
|
||||
auto &f = blocks[i]->f;
|
||||
for (const auto &pBlock : blocks) {
|
||||
auto &f = pBlock->f;
|
||||
const auto src = &*f;
|
||||
if (hash.count( src ) > 0) {
|
||||
const auto &dst = hash[src];
|
||||
@ -156,6 +152,7 @@ void FindDependencies(AudacityProject *project,
|
||||
// all of those alias block files with disk block files.
|
||||
static void RemoveDependencies(AudacityProject *project,
|
||||
AliasedFileArray &aliasedFiles)
|
||||
// STRONG-GUARANTEE
|
||||
{
|
||||
const auto &dirManager = project->GetDirManager();
|
||||
|
||||
@ -198,6 +195,8 @@ static void RemoveDependencies(AudacityProject *project,
|
||||
BlockFilePtr newBlockFile;
|
||||
{
|
||||
SampleBuffer buffer(len, format);
|
||||
// We tolerate exceptions from NewSimpleBlockFile and so we
|
||||
// can allow exceptions from ReadData too
|
||||
f->ReadData(buffer.ptr(), format, 0, len);
|
||||
newBlockFile =
|
||||
dirManager->NewSimpleBlockFile(buffer.ptr(), len, format);
|
||||
@ -210,15 +209,18 @@ static void RemoveDependencies(AudacityProject *project,
|
||||
completedBytes += SAMPLE_SIZE(format) * len;
|
||||
updateResult = progress.Update(completedBytes, totalBytesToProcess);
|
||||
if (updateResult != ProgressResult::Success)
|
||||
break;
|
||||
// leave the project unchanged
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// COMMIT OPERATIONS needing NOFAIL-GUARANTEE:
|
||||
|
||||
// Above, we created a SimpleBlockFile contained in our project
|
||||
// to go with each AliasBlockFile that we wanted to migrate.
|
||||
// However, that didn't actually change any references to these
|
||||
// blockfiles in the Sequences, so we do that next...
|
||||
ReplaceBlockFiles(project, blockFileHash);
|
||||
ReplaceBlockFiles(blocks, blockFileHash);
|
||||
}
|
||||
|
||||
//
|
||||
@ -473,22 +475,22 @@ void DependencyDialog::OnYes(wxCommandEvent & WXUNUSED(event))
|
||||
|
||||
void DependencyDialog::OnCopySelectedFiles(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
AliasedFileArray aliasedFilesToDelete;
|
||||
AliasedFileArray aliasedFilesToDelete, remainingAliasedFiles;
|
||||
|
||||
long i = 0;
|
||||
for(auto iter = mAliasedFiles.begin(); iter != mAliasedFiles.end();) {
|
||||
if (mFileListCtrl->GetItemState(i, wxLIST_STATE_SELECTED)) {
|
||||
// Two-step move could be simplified when all compilers have C++11 vector
|
||||
aliasedFilesToDelete.push_back(AliasedFile{});
|
||||
aliasedFilesToDelete.back() = std::move(*iter);
|
||||
iter = mAliasedFiles.erase(iter);
|
||||
}
|
||||
for( const auto &file : mAliasedFiles ) {
|
||||
if (mFileListCtrl->GetItemState(i, wxLIST_STATE_SELECTED))
|
||||
aliasedFilesToDelete.push_back( file );
|
||||
else
|
||||
++iter;
|
||||
remainingAliasedFiles.push_back( file );
|
||||
++i;
|
||||
}
|
||||
|
||||
// provides STRONG-GUARANTEE
|
||||
RemoveDependencies(mProject, aliasedFilesToDelete);
|
||||
|
||||
// COMMIT OPERATIONS needing NOFAIL-GUARANTEE:
|
||||
mAliasedFiles.swap( remainingAliasedFiles );
|
||||
PopulateList();
|
||||
|
||||
if (mAliasedFiles.empty() || !mHasNonMissingFiles)
|
||||
|
Loading…
x
Reference in New Issue
Block a user