From 58f07d2021d239bb23cbf56afee24e2924ba58e1 Mon Sep 17 00:00:00 2001 From: Paul Licameli <paul.licameli@audacityteam.org> Date: Tue, 24 Oct 2017 14:46:32 -0400 Subject: [PATCH] Flush .aup before writing .au; no redundant out-of-space messages --- src/Project.cpp | 28 +++++++++++++++++++++------- src/xml/XMLWriter.cpp | 13 ++++++++++++- src/xml/XMLWriter.h | 8 ++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/Project.cpp b/src/Project.cpp index ec8c38f905..a1a1dd9966 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -3873,15 +3873,24 @@ bool AudacityProject::Save(bool overwrite /* = true */ , // Write the .aup now, before DirManager::SetProject, // because it's easier to clean up the effects of successful write of .aup // followed by failed SetProject, than the other way about. - // And that cleanup is done by the destructor of saveFile, if Commit() is + // And that cleanup is done by the destructor of saveFile, if PostCommit() is // not done. // (SetProject, when it fails, cleans itself up.) XMLFileWriter saveFile{ mFileName, _("Error Saving Project") }; success = GuardedCall< bool >( [&] { - WriteXMLHeader(saveFile); - WriteXML(saveFile, bWantSaveCompressed); - return true; - } ); + WriteXMLHeader(saveFile); + WriteXML(saveFile, bWantSaveCompressed); + // Flushes files, forcing space exhaustion errors before trying + // SetProject(): + saveFile.PreCommit(); + return true; + }, + MakeSimpleGuard(false), + // Suppress the usual error dialog for failed write, + // which is redundant here: + [](void*){} + ); + if (!success) return false; @@ -3920,9 +3929,14 @@ bool AudacityProject::Save(bool overwrite /* = true */ , // Commit the writing of the .aup only now, after we know that the _data // folder also saved with no problems. + // Error recovery in case this fails might not be correct -- there is no + // provision to undo the effects of SetProject -- but it is very unlikely + // that this will happen: only renaming and removing of files happens, + // not writes that might exhaust space. So DO give a second dialog in + // case the unusual happens. success = success && GuardedCall< bool >( [&] { - saveFile.Commit(); - return true; + saveFile.PostCommit(); + return true; } ); if (!success) diff --git a/src/xml/XMLWriter.cpp b/src/xml/XMLWriter.cpp index dd1904c024..a969b0b791 100644 --- a/src/xml/XMLWriter.cpp +++ b/src/xml/XMLWriter.cpp @@ -313,14 +313,25 @@ XMLFileWriter::~XMLFileWriter() void XMLFileWriter::Commit() // may throw +{ + PreCommit(); + PostCommit(); +} + +void XMLFileWriter::PreCommit() +// may throw { while (mTagstack.GetCount()) { EndTag(mTagstack[0]); } - auto tempPath = GetName(); CloseWithoutEndingTags(); +} +void XMLFileWriter::PostCommit() +// may throw +{ + auto tempPath = GetName(); if (mKeepBackup) { if (! mBackupFile.Close() || ! wxRenameFile( mOutputPath, mBackupName ) ) diff --git a/src/xml/XMLWriter.h b/src/xml/XMLWriter.h index e8262d7b00..11cb791cb2 100644 --- a/src/xml/XMLWriter.h +++ b/src/xml/XMLWriter.h @@ -86,8 +86,16 @@ class AUDACITY_DLL_API XMLFileWriter final : private wxFFile, public XMLWriter { /// Close all tags and then close the file. /// Might throw. If not, then create /// or modify the file at the output path. + /// Composed of two steps, PreCommit() and PostCommit() void Commit(); + /// Does the part of Commit that might fail because of exhaustion of space + void PreCommit(); + + /// Does other parts of Commit that are not likely to fail for exhaustion + /// of space, but might for other reasons + void PostCommit(); + /// Write to file. Might throw. void Write(const wxString &data) override; -- GitLab