1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-23 17:30:17 +01:00

Cross project copy data loss (#604)

* Need only CloseLock now, not old Lock and Unlock...

... which were for cross-project cut and paste, but they no longer work and we
need another solution.  So delete much old code.

* Fix dangling reference to AudacityProject completely! ...

... in SqliteSampleBlockFactory: retain ONLY the shared pointer to
ProjectFileIO, then pass that, not project, to constructors of blocks.

completing the work of 127696879d

* Restore part of the Bug2436 fix...

... which needs the non-default arguments to WaveTrack::EmptyCopy that got lost
at d39590cf41

So that pasted WaveTracks refer to the correct SampleBlockFactory and database
for their project

But this is not yet a sufficient re-fix for the bug

* Complete the fix for cross-project copies and 2436...

... by duplicating sample blocks, in Sequence.cpp, when it is wrong just to
share them.

And to determine which case it is, see whether source and destination Sequences
have the same sample block factories when doing Copy or Paste.  Duplicate
when the factories are different.  Otherwise sharing is safe and more space
efficient.

This does the analogous to what DirManager::CopyBlockFile did before commit
d39590c.
This commit is contained in:
Paul Licameli
2020-07-07 16:41:50 -04:00
committed by GitHub
parent 590d8c6d09
commit 875e8e0984
10 changed files with 78 additions and 152 deletions

View File

@@ -22,11 +22,9 @@ class SqliteSampleBlock final : public SampleBlock
{
public:
explicit SqliteSampleBlock(AudacityProject *project);
explicit SqliteSampleBlock(ProjectFileIO &io);
~SqliteSampleBlock() override;
void Lock() override;
void Unlock() override;
void CloseLock() override;
void SetSamples(samplePtr src, size_t numsamples, sampleFormat srcformat);
@@ -83,7 +81,7 @@ private:
bool mValid;
bool mDirty;
bool mSilent;
int mRefCnt;
bool mLocked = false;
SampleBlockID mBlockID;
@@ -131,13 +129,11 @@ public:
const wxChar **attrs) override;
private:
AudacityProject &mProject;
std::shared_ptr<ProjectFileIO> mpIO;
};
SqliteSampleBlockFactory::SqliteSampleBlockFactory( AudacityProject &project )
: mProject{ project }
, mpIO{ ProjectFileIO::Get(project).shared_from_this() }
: mpIO{ ProjectFileIO::Get(project).shared_from_this() }
{
}
@@ -147,7 +143,7 @@ SqliteSampleBlockFactory::~SqliteSampleBlockFactory() = default;
SampleBlockPtr SqliteSampleBlockFactory::DoCreate(
samplePtr src, size_t numsamples, sampleFormat srcformat )
{
auto sb = std::make_shared<SqliteSampleBlock>(&mProject);
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
sb->SetSamples(src, numsamples, srcformat);
return sb;
}
@@ -155,7 +151,7 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreate(
SampleBlockPtr SqliteSampleBlockFactory::DoCreateSilent(
size_t numsamples, sampleFormat srcformat )
{
auto sb = std::make_shared<SqliteSampleBlock>(&mProject);
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
sb->SetSilent(numsamples, srcformat);
return sb;
}
@@ -164,7 +160,7 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreateSilent(
SampleBlockPtr SqliteSampleBlockFactory::DoCreateFromXML(
sampleFormat srcformat, const wxChar **attrs )
{
auto sb = std::make_shared<SqliteSampleBlock>(&mProject);
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
sb->mSampleFormat = srcformat;
int found = 0;
@@ -230,17 +226,16 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreateFromXML(
SampleBlockPtr SqliteSampleBlockFactory::DoGet( SampleBlockID sbid )
{
auto sb = std::make_shared<SqliteSampleBlock>(&mProject);
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
sb->Load(sbid);
return sb;
}
SqliteSampleBlock::SqliteSampleBlock(AudacityProject *project)
: mIO(ProjectFileIO::Get(*project))
SqliteSampleBlock::SqliteSampleBlock(ProjectFileIO &io)
: mIO(io)
{
mValid = false;
mSilent = false;
mRefCnt = 0;
mBlockID = 0;
@@ -258,7 +253,7 @@ SqliteSampleBlock::SqliteSampleBlock(AudacityProject *project)
SqliteSampleBlock::~SqliteSampleBlock()
{
// See ProjectFileIO::Bypass() for a description of mIO.mBypass
if (mRefCnt == 0 && !mIO.ShouldBypass())
if (!mLocked && !mIO.ShouldBypass())
{
// In case Delete throws, don't let an exception escape a destructor,
// but we can still enqueue the delayed handler so that an error message
@@ -269,19 +264,9 @@ SqliteSampleBlock::~SqliteSampleBlock()
}
}
void SqliteSampleBlock::Lock()
{
++mRefCnt;
}
void SqliteSampleBlock::Unlock()
{
--mRefCnt;
}
void SqliteSampleBlock::CloseLock()
{
Lock();
mLocked = true;
}
SampleBlockID SqliteSampleBlock::GetBlockID()