1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-06 14:52:34 +02:00

Manage block files with std::shared_ptr, BlockHash stores weak_ptr

This commit is contained in:
Paul Licameli 2016-08-16 10:52:43 -04:00
parent 84ccdca5c3
commit 8b72bd2f92
14 changed files with 51 additions and 230 deletions

View File

@ -101,7 +101,6 @@ ArrayOf<char> BlockFile::fullSummary;
/// @param samples The number of samples this BlockFile contains.
BlockFile::BlockFile(wxFileNameWrapper &&fileName, sampleCount samples):
mLockCount(0),
mRefCount(1),
mFileName(std::move(fileName)),
mLen(samples),
mSummaryInfo(samples)
@ -165,28 +164,6 @@ bool BlockFile::IsLocked()
return mLockCount > 0;
}
/// Increases the reference count of this block by one. Only
/// DirManager should call this method.
void BlockFile::Ref() const
{
mRefCount++;
BLOCKFILE_DEBUG_OUTPUT("Ref", mRefCount);
}
/// Decreases the reference count of this block by one. If this
/// causes the count to become zero, deletes the associated disk
/// file and deletes this object
bool BlockFile::Deref() const
{
mRefCount--;
BLOCKFILE_DEBUG_OUTPUT("Deref", mRefCount);
if (mRefCount <= 0) {
delete this;
return true;
} else
return false;
}
/// Get a buffer containing a summary block describing this sample
/// data. This must be called by derived classes when they
/// are constructed, to allow them to construct their summary data,

View File

@ -44,15 +44,12 @@ class SummaryInfo {
class BlockFile;
using BlockFilePtr = std::shared_ptr<BlockFile>;
// to do: use shared_ptr instead
using BlockFilePtr = BlockFile *;
// to do: make this a synonym for make_shared
template< typename Result, typename... Args >
inline Result *make_blockfile (Args && ... args)
inline std::shared_ptr< Result > make_blockfile (Args && ... args)
{
return new Result( std::forward< Args > ( args )... );
return std::make_shared< Result > ( std::forward< Args > ( args )... );
}
class PROFILE_DLL_API BlockFile /* not final, abstract */ {
@ -168,17 +165,6 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
private:
friend class DirManager;
friend class AudacityApp;
//needed for Ref/Deref access.
friend class ODComputeSummaryTask;
friend class ODDecodeTask;
friend class ODPCMAliasBlockFile;
virtual void Ref() const;
virtual bool Deref() const;
virtual int RefCount(){return mRefCount;}
protected:
/// Calculate summary data for the given sample data
/// Overrides have differing details of memory management
@ -199,7 +185,6 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
private:
int mLockCount;
mutable int mRefCount;
static ArrayOf<char> fullSummary;

View File

@ -94,10 +94,6 @@ static void ReplaceBlockFiles(AudacityProject *project,
const auto src = &*f;
if (hash.count( src ) > 0) {
const auto &dst = hash[src];
dirManager->Deref(src);
dirManager->Ref(dst);
f = dst;
}
}
@ -223,11 +219,6 @@ static void RemoveDependencies(AudacityProject *project,
// However, that didn't actually change any references to these
// blockfiles in the Sequences, so we do that next...
ReplaceBlockFiles(project, blockFileHash);
// Subtract one from reference count of NEW block files; they're
// now all referenced the proper number of times by the Sequences
for (const auto &pair : blockFileHash)
dirManager->Deref(pair.second);
}
//

View File

@ -454,7 +454,7 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
int count = 0;
while ((iter != mBlockFileHash.end()) && success)
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -486,7 +486,7 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
BlockHash::iterator iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -726,7 +726,7 @@ auto DirManager::GetBalanceInfo() -> BalanceInfo &
auto it = mBlockFileHash.begin(), end = mBlockFileHash.end();
while (it != end)
{
BlockFilePtr ptr { it->second };
BlockFilePtr ptr { it->second.lock() };
if (!ptr) {
auto name = it->first;
mBlockFileHash.erase( it++ );
@ -1006,7 +1006,7 @@ bool DirManager::ContainsBlockFile(const BlockFile *b) const
BlockHash::const_iterator it = mBlockFileHash.find(result.name.GetName());
if (it == mBlockFileHash.end())
return false;
BlockFilePtr ptr = it->second;
BlockFilePtr ptr = it->second.lock();
return ptr && (b == &*ptr);
}
@ -1015,7 +1015,7 @@ bool DirManager::ContainsBlockFile(const wxString &filepath) const
// check what the hash returns in case the blockfile is from a different project
BlockHash::const_iterator it = mBlockFileHash.find(filepath);
return it != mBlockFileHash.end() &&
BlockFilePtr{ it->second };
BlockFilePtr{ it->second.lock() };
}
// Adds one to the reference count of the block file,
@ -1027,7 +1027,6 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
const auto &fn = result.name;
if (!b->IsLocked()) {
b->Ref();
//mchinen:July 13 2009 - not sure about this, but it needs to be added to the hash to be able to save if not locked.
//note that this shouldn't hurt mBlockFileHash's that already contain the filename, since it should just overwrite.
//but it's something to watch out for.
@ -1148,7 +1147,6 @@ bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
// See http://bugzilla.audacityteam.org/show_bug.cgi?id=451#c13.
// Lock pBlockFile so that the ~BlockFile() will not DELETE the file on disk.
pBlockFile->Lock();
delete pBlockFile;
return false;
}
else
@ -1162,7 +1160,7 @@ bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
wxString name = target->GetFileName().name.GetName();
auto &wRetrieved = mBlockFileHash[name];
BlockFilePtr retrieved = wRetrieved;
BlockFilePtr retrieved = wRetrieved.lock();
if (retrieved) {
// Lock it in order to DELETE it safely, i.e. without having
// it DELETE the file, too...
@ -1260,38 +1258,6 @@ bool DirManager::CopyToNewProjectDirectory(BlockFile *f)
return MoveOrCopyToNewProjectDirectory(f, true);
}
void DirManager::Ref(BlockFile * f)
{
f->Ref();
//printf("Ref(%d): %s\n",
// f->mRefCount,
// (const char *)f->mFileName.GetFullPath().mb_str());
}
int DirManager::GetRefCount(BlockFile * f)
{
return f->mRefCount;
}
void DirManager::Deref(BlockFile * f)
{
const wxString theFileName = f->GetFileName().name.GetName();
//printf("Deref(%d): %s\n",
// f->mRefCount-1,
// (const char *)f->mFileName.GetFullPath().mb_str());
if (f->Deref()) {
// If Deref() returned true, the reference count reached zero
// and this block is no longer needed. Remove it from the hash
// table.
mBlockFileHash.erase(theFileName);
BalanceInfoDel(theFileName);
}
}
bool DirManager::EnsureSafeFilename(const wxFileName &fName)
{
// Quick check: If it's not even in our alias list,
@ -1352,7 +1318,7 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
BlockHash::iterator iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -1395,7 +1361,7 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
BlockHash::iterator iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -1423,7 +1389,7 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
BlockHash::iterator iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -1558,7 +1524,7 @@ _("Project check of \"%s\" folder \
while (iter != missingAliasedFileAUFHash.end())
{
// This type cast is safe. We checked that it's an alias block file earlier.
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
wxASSERT(b);
if (!b)
@ -1625,7 +1591,7 @@ _("Project check of \"%s\" folder \
BlockHash::iterator iter = missingAUFHash.begin();
while (iter != missingAUFHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
wxASSERT(b);
if (!b)
@ -1689,7 +1655,7 @@ _("Project check of \"%s\" folder \
BlockHash::iterator iter = missingAUHash.begin();
while (iter != missingAUHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
wxASSERT(b);
if (!b)
@ -1801,7 +1767,7 @@ void DirManager::FindMissingAliasedFiles(
while (iter != mBlockFileHash.end())
{
wxString key = iter->first; // file name and extension
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -1841,7 +1807,7 @@ void DirManager::FindMissingAUFs(
while (iter != mBlockFileHash.end())
{
const wxString &key = iter->first;
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -1871,7 +1837,7 @@ void DirManager::FindMissingAUs(
while (iter != mBlockFileHash.end())
{
const wxString &key = iter->first;
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -1975,7 +1941,7 @@ void DirManager::FillBlockfilesCache()
iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -1995,7 +1961,7 @@ void DirManager::FillBlockfilesCache()
int current = 0;
while (iter != mBlockFileHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -2020,7 +1986,7 @@ void DirManager::WriteCacheToDisk()
iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
@ -2040,7 +2006,7 @@ void DirManager::WriteCacheToDisk()
int current = 0;
while (iter != mBlockFileHash.end())
{
BlockFilePtr b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;

View File

@ -34,9 +34,10 @@ class SequenceTest;
WX_DECLARE_HASH_MAP(int, int, wxIntegerHash, wxIntegerEqual, DirHash);
class BlockFile;
using BlockFilePtr = BlockFile *;
using BlockFilePtr = std::shared_ptr<BlockFile>;
WX_DECLARE_HASH_MAP(wxString, BlockFilePtr, wxStringHash, wxStringEqual, BlockHash);
WX_DECLARE_HASH_MAP(wxString, std::weak_ptr<BlockFile>, wxStringHash,
wxStringEqual, BlockHash);
wxMemorySize GetFreeMemory();
@ -101,12 +102,6 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
bool EnsureSafeFilename(const wxFileName &fName);
void Ref(BlockFile * f);
void Deref(BlockFile * f);
// For debugging only
int GetRefCount(BlockFile * f);
void SetLoadingTarget(BlockArray *pArray, unsigned idx)
{
mLoadingTarget = pArray;

View File

@ -34,6 +34,7 @@ using std::isinf;
namespace std {
using std::tr1::shared_ptr;
using std::tr1::weak_ptr;
using std::tr1::static_pointer_cast;
using std::tr1::remove_reference;
template<typename X> struct default_delete

View File

@ -75,19 +75,6 @@ Sequence::Sequence(const Sequence &orig, const std::shared_ptr<DirManager> &proj
Sequence::~Sequence()
{
DerefAllFiles();
}
void Sequence::DerefAllFiles()
{
for (size_t i = 0, nn = mBlock.size(); i < nn; i++)
{
BlockFile *& pOldFile = mBlock[i].f;
if (pOldFile) {
mDirManager->Deref(pOldFile);
pOldFile = NULL;
}
}
}
sampleCount Sequence::GetMaxBlockSize() const
@ -210,8 +197,6 @@ bool Sequence::ConvertToSampleFormat(sampleFormat format, bool* pbChanged)
// Invalidate all the old, non-aliased block files.
// Aliased files will be converted at save, per comment above.
DerefAllFiles();
// Replace with NEW blocks.
mBlock.swap(newBlockArray);
}
@ -550,7 +535,6 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
auto file =
mDirManager->NewSimpleBlockFile(buffer.ptr(), largerBlockLen, mSampleFormat);
mDirManager->Deref(block.f);
block.f = file;
for (unsigned int i = b + 1; i < numBlocks; i++)
@ -635,8 +619,6 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
Blockify(newBlock, s + lastStart, sampleBuffer.ptr(), rightLen);
}
mDirManager->Deref(splitBlock.f);
// Copy remaining blocks to NEW block array and
// swap the NEW block array in for the old
for (i = b + 1; i < numBlocks; i++)
@ -681,13 +663,10 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
silentFile = make_blockfile<SilentBlockFile>(idealSamples);
while (len >= idealSamples) {
sTrack.mBlock.push_back(SeqBlock(silentFile, pos));
mDirManager->Ref(silentFile);
pos += idealSamples;
len -= idealSamples;
}
if (silentFile)
mDirManager->Deref(silentFile);
if (len) {
sTrack.mBlock.push_back(SeqBlock(
make_blockfile<SilentBlockFile>(len), pos));
@ -1151,11 +1130,8 @@ bool Sequence::CopyWrite(SampleBuffer &scratch,
Read(scratch.ptr(), mSampleFormat, b, 0, length);
memcpy(scratch.ptr() + start*sampleSize, buffer, len*sampleSize);
BlockFile *const oldBlockFile = b.f;
b.f = mDirManager->NewSimpleBlockFile(scratch.ptr(), length, mSampleFormat);
mDirManager->Deref(oldBlockFile);
return true;
}
@ -1233,7 +1209,6 @@ bool Sequence::Set(samplePtr buffer, sampleFormat format,
if (start == block.start &&
blen == fileLength) {
mDirManager->Deref(block.f);
block.f = make_blockfile<SilentBlockFile>(blen);
}
else {
@ -1545,7 +1520,6 @@ bool Sequence::Append(samplePtr buffer, sampleFormat format,
static_cast< SimpleBlockFile * >( &*newLastBlock.f )
->SaveXML( *blockFileLog );
mDirManager->Deref(lastBlock.f);
lastBlock = newLastBlock;
len -= addLen;
@ -1651,12 +1625,10 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
Read(scratch.ptr() + (pos * sampleSize), mSampleFormat,
b, pos + len, newLen - pos);
BlockFile *const oldFile = b.f;
b = SeqBlock(
mDirManager->NewSimpleBlockFile(scratch.ptr(), newLen, mSampleFormat),
b.start
);
mDirManager->Deref(oldFile);
for (unsigned int j = b0 + 1; j < numBlocks; j++)
mBlock[j].start -= len;
@ -1705,8 +1677,6 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
newBlock.erase(newBlock.end() - 1);
Blockify(newBlock, prepreBlock.start, scratch.ptr(), sum);
mDirManager->Deref(prepreBlock.f);
}
}
else {
@ -1714,15 +1684,6 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
// right on the beginning of a block.
}
if (b0 != b1) {
mDirManager->Deref(preBlock.f);
}
// Next, DELETE blocks strictly between b0 and b1
for (i = b0 + 1; i < b1; i++) {
mDirManager->Deref(mBlock[i].f);
}
// Now, symmetrically, grab the samples in block b1 after the
// deletion point into postBuffer. If this is enough samples
// for its own block, or if this would be the last block in
@ -1757,15 +1718,12 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
Blockify(newBlock, start, scratch.ptr(), sum);
b1++;
mDirManager->Deref(postpostBlock.f);
}
}
else {
// The sample where we begin deletion happens to fall
// right on the end of a block.
}
mDirManager->Deref(postBlock.f);
// Copy the remaining blocks over from the old array
for (i = b1 + 1; i < numBlocks; i++)
@ -1822,11 +1780,11 @@ void Sequence::DebugPrintf(wxString *dest) const
for (i = 0; i < mBlock.size(); i++) {
const SeqBlock &seqBlock = mBlock[i];
*dest += wxString::Format
(wxT(" Block %3u: start %8lld, len %8lld, refs %d, "),
(wxT(" Block %3u: start %8lld, len %8lld, refs %ld, "),
i,
(long long) seqBlock.start,
seqBlock.f ? (long long) seqBlock.f->GetLength() : 0,
seqBlock.f ? mDirManager->GetRefCount(seqBlock.f) : 0);
seqBlock.f ? seqBlock.f.use_count() : 0);
if (seqBlock.f)
*dest += seqBlock.f->GetFileName().name.GetFullName();

View File

@ -30,7 +30,7 @@ typedef wxLongLong_t sampleCount; /** < A native 64-bit integer type, because
#endif
class BlockFile;
using BlockFilePtr = BlockFile *;
using BlockFilePtr = std::shared_ptr<BlockFile>;
class DirManager;
@ -238,8 +238,6 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
// Private methods
//
void DerefAllFiles();
int FindBlock(sampleCount pos) const;
bool AppendBlock(const SeqBlock &b);

View File

@ -74,33 +74,6 @@ ODPCMAliasBlockFile::~ODPCMAliasBlockFile()
{
}
/// Increases the reference count of this block by one. Only
/// DirManager should call this method.
/// This method has been overidden to be threadsafe. It is important especially
/// if two blockfiles deref at the same time resulting in a double deletion of the file
void ODPCMAliasBlockFile::Ref() const
{
mRefMutex.Lock();
BlockFile::Ref();
mRefMutex.Unlock();
}
/// Decreases the reference count of this block by one. If this
/// causes the count to become zero, deletes the associated disk
/// file and deletes this object
bool ODPCMAliasBlockFile::Deref() const
{
bool ret;
mDerefMutex.Lock();
ret = BlockFile::Deref();
if(!ret)
{
//Deref returns true when deleted, in which case we should not be touching instance variables, or ever calling this function again.
mDerefMutex.Unlock();
}
return ret;
}
//Check to see if we have the file for these calls.

View File

@ -143,13 +143,6 @@ protected:
sampleFormat format, ArrayOf<char> &cleanup) override;
private:
//Thread-safe versions
void Ref() const override;
bool Deref() const override;
//needed for Ref/Deref access.
friend class DirManager;
friend class ODComputeSummaryTask;
friend class ODDecodeTask;
ODLock mWriteSummaryMutex;
@ -162,11 +155,6 @@ protected:
//lock the read data - libsndfile can't handle two reads at once?
mutable ODLock mReadDataMutex;
//lock the Ref counting
mutable ODLock mDerefMutex;
mutable ODLock mRefMutex;
mutable ODLock mSummaryAvailableMutex;
bool mSummaryAvailable;
bool mSummaryBeingComputed;

View File

@ -49,8 +49,6 @@ void ODComputeSummaryTask::Terminate()
//The terminate block won't allow DoSomeInternal and this method to be run async, so this is thread-safe.
//Deref the block files since they are ref'ed when put into the array.
mBlockFilesMutex.Lock();
for(unsigned int i=0;i<mBlockFiles.size();i++)
mBlockFiles[i]->Deref();
mBlockFiles.clear();
mBlockFilesMutex.Unlock();
}
@ -78,7 +76,7 @@ void ODComputeSummaryTask::DoSomeInternal()
//first check to see if the ref count is at least 2. It should have one
//from when we added it to this instance's mBlockFiles array, and one from
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
if(bf->RefCount()>=2)
if(bf.use_count() >= 2)
{
bf->DoWriteSummary();
success = true;
@ -93,8 +91,6 @@ void ODComputeSummaryTask::DoSomeInternal()
mMaxBlockFiles--;
}
//Release the refcount we placed on it.
bf->Deref();
//take it out of the array - we are done with it.
mBlockFiles.erase(mBlockFiles.begin());
@ -169,7 +165,7 @@ void ODComputeSummaryTask::CalculatePercentComplete()
///by default left to right, or frome the point the user has clicked.
void ODComputeSummaryTask::Update()
{
std::vector<ODPCMAliasBlockFile*> tempBlocks;
std::vector< std::shared_ptr< ODPCMAliasBlockFile > > tempBlocks;
mWaveTrackMutex.Lock();
@ -204,8 +200,8 @@ void ODComputeSummaryTask::Update()
const auto &file = block.f;
if(file->IsDataAvailable() && !file->IsSummaryAvailable())
{
file->Ref();
ODPCMAliasBlockFile *const odpcmaFile = static_cast<ODPCMAliasBlockFile*>(file);
const auto odpcmaFile =
std::static_pointer_cast<ODPCMAliasBlockFile>(file);
odpcmaFile->SetStart(block.start);
odpcmaFile->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
@ -234,11 +230,9 @@ void ODComputeSummaryTask::Update()
///Computes the summary calculation queue order of the blockfiles
void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &unorderedBlocks)
void ODComputeSummaryTask::OrderBlockFiles
(std::vector< std::shared_ptr< ODPCMAliasBlockFile > > &unorderedBlocks)
{
//we are going to take things out of the array. But first deref them since we ref them when we put them in.
for(unsigned int i=0;i<mBlockFiles.size();i++)
mBlockFiles[i]->Deref();
mBlockFiles.clear();
//Order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
@ -252,7 +246,7 @@ void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &un
//check to see if the refcount is at least two before we add it to the list.
//There should be one Ref() from the one added by this ODTask, and one from the track.
//If there isn't, then the block was deleted for some reason and we should ignore it.
if(unorderedBlocks[i]->RefCount()>=2)
if(unorderedBlocks[i].use_count() >= 2)
{
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
//and add ones that are closer.
@ -276,7 +270,6 @@ void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &un
else
{
//Otherwise, let it be deleted and forget about it.
unorderedBlocks[i]->Deref();
}
}
}

View File

@ -64,7 +64,8 @@ protected:
void Update() override;
///Orders the input as either On-Demand or default layered order.
void OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &unorderedBlocks);
void OrderBlockFiles
(std::vector< std::shared_ptr< ODPCMAliasBlockFile > > &unorderedBlocks);
///tells us whether or not Update has been run at least once.
void MarkUpdateRan();
@ -72,7 +73,7 @@ protected:
//mBlockFiles is touched on several threads- the OD terminate thread, and the task thread, so we need to mutex it.
ODLock mBlockFilesMutex;
std::vector<ODPCMAliasBlockFile*> mBlockFiles;
std::vector< std::shared_ptr< ODPCMAliasBlockFile > > mBlockFiles;
int mMaxBlockFiles;
int mComputedBlockFiles;
ODLock mHasUpdateRanMutex;

View File

@ -56,7 +56,7 @@ void ODDecodeTask::DoSomeInternal()
//first check to see if the ref count is at least 2. It should have one
//from when we added it to this instance's mBlockFiles array, and one from
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
if(bf->RefCount()>=2)
if(bf.use_count()>=2)
{
//OD TODO: somehow pass the bf a reference to the decoder that manages it's file.
//we need to ensure that the filename won't change or be moved. We do this by calling LockRead(),
@ -86,7 +86,6 @@ void ODDecodeTask::DoSomeInternal()
//Release the refcount we placed on it if we are successful
if(ret >= 0 ) {
bf->Deref();
//take it out of the array - we are done with it.
mBlockFiles.erase(mBlockFiles.begin());
@ -126,8 +125,7 @@ bool ODDecodeTask::SeekingAllowed()
///by default creates the order of the wavetrack to load.
void ODDecodeTask::Update()
{
std::vector<ODDecodeBlockFile*> tempBlocks;
std::vector< std::shared_ptr< ODDecodeBlockFile > > tempBlocks;
mWaveTrackMutex.Lock();
@ -154,12 +152,12 @@ void ODDecodeTask::Update()
{
//since we have more than one ODBlockFile, we will need type flags to cast.
SeqBlock &block = (*blocks)[i];
BlockFile *const file = block.f;
ODDecodeBlockFile *oddbFile;
const auto &file = block.f;
std::shared_ptr<ODDecodeBlockFile> oddbFile;
if (!file->IsDataAvailable() &&
(oddbFile = static_cast<ODDecodeBlockFile*>(file))->GetDecodeType() == this->GetODType())
(oddbFile =
std::static_pointer_cast<ODDecodeBlockFile>(file))->GetDecodeType() == this->GetODType())
{
file->Ref();
oddbFile->SetStart(block.start);
oddbFile->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
@ -186,11 +184,9 @@ void ODDecodeTask::Update()
///Orders the input as either On-Demand or default layered order.
void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlocks)
void ODDecodeTask::OrderBlockFiles
(std::vector< std::shared_ptr< ODDecodeBlockFile > > &unorderedBlocks)
{
//we are going to take things out of the array. But first deref them since we ref them when we put them in.
for(unsigned int i=0;i<mBlockFiles.size();i++)
mBlockFiles[i]->Deref();
mBlockFiles.clear();
//TODO:order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
@ -203,7 +199,7 @@ void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlo
//check to see if the refcount is at least two before we add it to the list.
//There should be one Ref() from the one added by this ODTask, and one from the track.
//If there isn't, then the block was deleted for some reason and we should ignore it.
if(unorderedBlocks[i]->RefCount()>=2)
if(unorderedBlocks[i].use_count() >= 2)
{
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
//and add ones that are closer.
@ -227,8 +223,6 @@ void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlo
}
else
{
//Otherwise, let it be deleted and forget about it.
unorderedBlocks[i]->Deref();
}
}

View File

@ -85,10 +85,11 @@ protected:
void Update() override;
///Orders the input as either On-Demand or default layered order.
void OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlocks);
void OrderBlockFiles
(std::vector< std::shared_ptr< ODDecodeBlockFile > > &unorderedBlocks);
std::vector<ODDecodeBlockFile*> mBlockFiles;
std::vector<std::shared_ptr<ODDecodeBlockFile>> mBlockFiles;
std::vector<movable_ptr<ODFileDecoder>> mDecoders;
int mMaxBlockFiles;