1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-05 06:39:26 +02:00

Remove some naked new amd delete in: ondemand

This commit is contained in:
Paul Licameli 2016-04-06 19:09:53 -04:00 committed by Paul Licameli
parent f82ff73578
commit 473e955da3
15 changed files with 112 additions and 127 deletions

View File

@ -3000,8 +3000,7 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
TrackListIterator triter(GetTracks());
tr = triter.First();
std::vector<ODTask*> newTasks;
ODTask* newTask;
std::vector<movable_ptr<ODTask>> newTasks;
//std::vector<ODDecodeTask*> decodeTasks;
unsigned int createdODTasks=0;
while (tr) {
@ -3021,16 +3020,16 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
//we want at most one instance of each class for the project
while((odFlags|createdODTasks) != createdODTasks)
{
newTask=NULL;
movable_ptr<ODTask> newTask;
#ifdef EXPERIMENTAL_OD_FLAC
if(!(createdODTasks&ODTask::eODFLAC) && odFlags & ODTask::eODFLAC) {
newTask= new ODDecodeFlacTask;
newTask = make_movable<ODDecodeFlacTask>();
createdODTasks= createdODTasks | ODTask::eODFLAC;
}
else
#endif
if(!(createdODTasks&ODTask::eODPCMSummary) && odFlags & ODTask::eODPCMSummary) {
newTask=new ODComputeSummaryTask;
newTask = make_movable<ODComputeSummaryTask>();
createdODTasks= createdODTasks | ODTask::eODPCMSummary;
}
else {
@ -3041,14 +3040,14 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
if(newTask)
{
newTask->AddWaveTrack((WaveTrack*)tr);
newTasks.push_back(newTask);
newTasks.push_back(std::move(newTask));
}
}
}
tr = triter.Next();
}
for(unsigned int i=0;i<newTasks.size();i++)
ODManager::Instance()->AddNewTask(newTasks[i]);
ODManager::Instance()->AddNewTask(std::move(newTasks[i]));
//release the flag.
ODManager::UnmarkLoadedODFlag();
@ -4167,7 +4166,7 @@ void AudacityProject::PopState(const UndoState &state)
TrackListIterator iter(tracks);
Track *t = iter.First();
bool odUsed = false;
ODComputeSummaryTask* computeTask = NULL;
movable_ptr<ODComputeSummaryTask> computeTask;
while (t)
{
@ -4187,7 +4186,7 @@ void AudacityProject::PopState(const UndoState &state)
{
if(!odUsed)
{
computeTask=new ODComputeSummaryTask;
computeTask = make_movable<ODComputeSummaryTask>();
odUsed=true;
}
computeTask->AddWaveTrack((WaveTrack*)copyTrack);
@ -4198,7 +4197,7 @@ void AudacityProject::PopState(const UndoState &state)
//add the task.
if(odUsed)
ODManager::Instance()->AddNewTask(computeTask);
ODManager::Instance()->AddNewTask(std::move(computeTask));
HandleResize();

View File

@ -578,13 +578,13 @@ int FFmpegImportFileHandle::Import(TrackFactory *trackFactory,
//at this point we know the file is good and that we have to load the number of channels in mScs[s]->m_stream->codec->channels;
//so for OD loading we create the tracks and releasee the modal lock after starting the ODTask.
if (mUsingOD) {
std::vector<ODDecodeFFmpegTask*> tasks;
std::vector<movable_ptr<ODDecodeFFmpegTask>> tasks;
//append blockfiles to each stream and add an individual ODDecodeTask for each one.
s = -1;
for (const auto &stream : mChannels) {
++s;
ODDecodeFFmpegTask* odTask =
new ODDecodeFFmpegTask(mScs, ODDecodeFFmpegTask::FromList(mChannels), mContext, s);
auto odTask =
make_movable<ODDecodeFFmpegTask>(mScs, ODDecodeFFmpegTask::FromList(mChannels), mContext, s);
odTask->CreateFileDecoder(mFilename);
//each stream has different duration. We need to know it if seeking is to be allowed.
@ -619,17 +619,12 @@ int FFmpegImportFileHandle::Import(TrackFactory *trackFactory,
break;
}
}
tasks.push_back(odTask);
tasks.push_back(std::move(odTask));
}
//Now we add the tasks and let them run, or DELETE them if the user cancelled
for(int i=0; i < (int)tasks.size(); i++) {
if(res==eProgressSuccess)
ODManager::Instance()->AddNewTask(tasks[i]);
else
{
delete tasks[i];
}
}
if (res == eProgressSuccess)
for (int i = 0; i < (int)tasks.size(); i++)
ODManager::Instance()->AddNewTask(std::move(tasks[i]));
} else {
#endif

View File

@ -178,7 +178,7 @@ private:
bool mStreamInfoDone;
int mUpdateResult;
TrackHolders mChannels;
ODDecodeFlacTask *mDecoderTask;
movable_ptr<ODDecodeFlacTask> mDecoderTask;
};
@ -349,13 +349,11 @@ FLACImportFileHandle::FLACImportFileHandle(const wxString & name)
bool FLACImportFileHandle::Init()
{
#ifdef EXPERIMENTAL_OD_FLAC
mDecoderTask=new ODDecodeFlacTask;
mDecoderTask = make_movable<ODDecodeFlacTask>();
ODFlacDecoder* odDecoder = (ODFlacDecoder*)mDecoderTask->CreateFileDecoder(mFilename);
if(!odDecoder || !odDecoder->ReadHeader())
{
//DELETE the task only if it failed to read - otherwise the OD man takes care of it.
delete mDecoderTask;
return false;
}
//copy the meta data over to the class
@ -511,13 +509,13 @@ int FLACImportFileHandle::Import(TrackFactory *trackFactory,
if(moreThanStereo)
{
//if we have 3 more channels, they get imported on seperate tracks, so we add individual tasks for each.
ODManager::Instance()->AddNewTask(mDecoderTask);
mDecoderTask = new ODDecodeFlacTask; //TODO: see if we need to use clone to keep the metadata.
ODManager::Instance()->AddNewTask(std::move(mDecoderTask));
mDecoderTask = make_movable<ODDecodeFlacTask>(); //TODO: see if we need to use clone to keep the metadata.
}
}
//if we have mono or a linked track (stereo), we add ONE task for the one linked wave track
if(!moreThanStereo)
ODManager::Instance()->AddNewTask(mDecoderTask);
ODManager::Instance()->AddNewTask(std::move(mDecoderTask));
}
//END OD

View File

@ -408,7 +408,7 @@ int PCMImportFileHandle::Import(TrackFactory *trackFactory,
if(useOD)
{
ODComputeSummaryTask* computeTask=new ODComputeSummaryTask;
auto computeTask = make_movable<ODComputeSummaryTask>();
bool moreThanStereo = mInfo.channels>2;
for (const auto &channel : channels)
{
@ -416,13 +416,13 @@ int PCMImportFileHandle::Import(TrackFactory *trackFactory,
if(moreThanStereo)
{
//if we have 3 more channels, they get imported on seperate tracks, so we add individual tasks for each.
ODManager::Instance()->AddNewTask(computeTask);
computeTask=new ODComputeSummaryTask;
ODManager::Instance()->AddNewTask(std::move(computeTask));
computeTask = make_movable<ODComputeSummaryTask>();
}
}
//if we have a linked track, we add ONE task.
if(!moreThanStereo)
ODManager::Instance()->AddNewTask(computeTask);
ODManager::Instance()->AddNewTask(std::move(computeTask));
}
}
else {

View File

@ -35,9 +35,9 @@ ODComputeSummaryTask::ODComputeSummaryTask()
mHasUpdateRan=false;
}
std::unique_ptr<ODTask> ODComputeSummaryTask::Clone() const
movable_ptr<ODTask> ODComputeSummaryTask::Clone() const
{
auto clone = std::make_unique<ODComputeSummaryTask>();
auto clone = make_movable<ODComputeSummaryTask>();
clone->mDemandSample = GetDemandSample();
return std::move(clone);
}

View File

@ -36,7 +36,7 @@ class ODComputeSummaryTask final : public ODTask
ODComputeSummaryTask();
virtual ~ODComputeSummaryTask(){};
std::unique_ptr<ODTask> Clone() const override;
movable_ptr<ODTask> Clone() const override;
///Subclasses should override to return respective type.
unsigned int GetODType() override { return eODPCMSummary; }

View File

@ -41,15 +41,18 @@ extern FFmpegLibs *FFmpegLibsInst();
#define kMaxSamplesInCache 4410000
//struct for caching the decoded samples to be used over multiple blockfiles
typedef struct _FFmpegDecodeCache
struct FFMpegDecodeCache
{
uint8_t* samplePtr;//interleaved samples
FFMpegDecodeCache() {}
~FFMpegDecodeCache() { free(samplePtr); }
uint8_t* samplePtr{};//interleaved samples
sampleCount start;
sampleCount len;
int numChannels;
AVSampleFormat samplefmt; // input (from libav) sample format
} FFMpegDecodeCache;
};
//------ ODFFmpegDecoder declaration and defs - here because we strip dependencies from .h files
@ -82,7 +85,7 @@ public:
bool SeekingAllowed() ;
private:
void InsertCache(FFMpegDecodeCache* cache);
void InsertCache(movable_ptr<FFMpegDecodeCache> &&cache);
//puts the actual audio samples into the blockfile's data array
int FillDataFromCache(samplePtr & data, sampleFormat outFormat, sampleCount & start, sampleCount& len, unsigned int channel);
@ -100,7 +103,7 @@ private:
ScsPtr mScs; //!< Pointer to array of pointers to stream contexts.
ODDecodeFFmpegTask::Streams mChannels;
std::shared_ptr<FFmpegContext> mContext; //!< Format description, also contains metadata and some useful info
std::vector<FFMpegDecodeCache*> mDecodeCache;
std::vector<movable_ptr<FFMpegDecodeCache>> mDecodeCache;
int mNumSamplesInCache;
sampleCount mCurrentPos; //the index of the next sample to be decoded
sampleCount mCurrentLen; //length of the last packet decoded
@ -140,9 +143,9 @@ ODDecodeFFmpegTask::~ODDecodeFFmpegTask()
}
std::unique_ptr<ODTask> ODDecodeFFmpegTask::Clone() const
movable_ptr<ODTask> ODDecodeFFmpegTask::Clone() const
{
auto clone = std::make_unique<ODDecodeFFmpegTask>(mScs, Streams{ mChannels }, mContext, mStreamIndex);
auto clone = make_movable<ODDecodeFFmpegTask>(mScs, Streams{ mChannels }, mContext, mStreamIndex);
clone->mDemandSample=GetDemandSample();
//the decoders and blockfiles should not be copied. They are created as the task runs.
@ -275,11 +278,7 @@ ODFFmpegDecoder::~ODFFmpegDecoder()
//DELETE our caches.
while(mDecodeCache.size())
{
free(mDecodeCache[0]->samplePtr);
delete mDecodeCache[0];
mDecodeCache.erase(mDecodeCache.begin());
}
DropFFmpegLibs();
}
@ -389,7 +388,7 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
if(actualDecodeStart>start && firstpass) {
// find the number of samples for the leading silence
int amt = actualDecodeStart - start;
FFMpegDecodeCache* cache = new FFMpegDecodeCache;
auto cache = make_movable<FFMpegDecodeCache>();
//printf("skipping/zeroing %i samples. - now:%llu (%f), last:%llu, lastlen:%llu, start %llu, len %llu\n",amt,actualDecodeStart, actualDecodeStartdouble, mCurrentPos, mCurrentLen, start, len);
@ -409,7 +408,7 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
memset(cache->samplePtr, 0, amt * cache->numChannels * SAMPLE_SIZE(format));
InsertCache(cache);
InsertCache(std::move(cache));
}
firstpass=false;
mCurrentPos = actualDecodeStart;
@ -596,7 +595,7 @@ int ODFFmpegDecoder::DecodeFrame(streamContext *sc, bool flushing)
//TODO- consider growing/unioning a few cache buffers like WaveCache does.
//however we can't use wavecache as it isn't going to handle our stereo interleaved part, and isn't for samples
//However if other ODDecode tasks need this, we should do a NEW class for caching.
FFMpegDecodeCache* cache = new FFMpegDecodeCache;
auto cache = make_movable<FFMpegDecodeCache>();
//len is number of samples per channel
cache->numChannels = sc->m_stream->codec->channels;
@ -604,14 +603,14 @@ int ODFFmpegDecoder::DecodeFrame(streamContext *sc, bool flushing)
cache->start = mCurrentPos;
cache->samplePtr = (uint8_t*) malloc(sc->m_decodedAudioSamplesValidSiz);
cache->samplefmt = sc->m_samplefmt;
memcpy(cache->samplePtr, sc->m_decodedAudioSamples, sc->m_decodedAudioSamplesValidSiz);
memcpy(cache->samplePtr, sc->m_decodedAudioSamples.get(), sc->m_decodedAudioSamplesValidSiz);
InsertCache(cache);
InsertCache(std::move(cache));
}
return ret;
}
void ODFFmpegDecoder::InsertCache(FFMpegDecodeCache* cache) {
void ODFFmpegDecoder::InsertCache(movable_ptr<FFMpegDecodeCache> &&cache) {
int searchStart = 0;
int searchEnd = mDecodeCache.size(); //size() is also a valid insert index.
int guess = 0;
@ -634,7 +633,7 @@ void ODFFmpegDecoder::InsertCache(FFMpegDecodeCache* cache) {
}
mCurrentLen = cache->len;
mCurrentPos=cache->start+cache->len;
mDecodeCache.insert(mDecodeCache.begin()+guess, cache);
mDecodeCache.insert(mDecodeCache.begin()+guess, std::move(cache));
// mDecodeCache.push_back(cache);
mNumSamplesInCache+=cache->len;
@ -646,8 +645,6 @@ void ODFFmpegDecoder::InsertCache(FFMpegDecodeCache* cache) {
//drop which ever index is further from our newly added one.
dropindex = (guess > (int)mDecodeCache.size()/2) ? 0 : (mDecodeCache.size()-1);
mNumSamplesInCache-=mDecodeCache[dropindex]->len;
free(mDecodeCache[dropindex]->samplePtr);
delete mDecodeCache[dropindex];
mDecodeCache.erase(mDecodeCache.begin()+dropindex);
}
}

View File

@ -37,7 +37,7 @@ public:
ODDecodeFFmpegTask(const ScsPtr &scs, Streams &&channels, const std::shared_ptr<FFmpegContext> &context, int streamIndex);
virtual ~ODDecodeFFmpegTask();
std::unique_ptr<ODTask> Clone() const override;
movable_ptr<ODTask> Clone() const override;
///Creates an ODFileDecoder that decodes a file of filetype the subclass handles.
ODFileDecoder* CreateFileDecoder(const wxString & fileName) override;

View File

@ -33,9 +33,9 @@ ODDecodeFlacTask::~ODDecodeFlacTask()
}
std::unique_ptr<ODTask> ODDecodeFlacTask::Clone() const
movable_ptr<ODTask> ODDecodeFlacTask::Clone() const
{
auto clone = std::make_unique<ODDecodeFlacTask>();
auto clone = make_movable<ODDecodeFlacTask>();
clone->mDemandSample = GetDemandSample();
//the decoders and blockfiles should not be copied. They are created as the task runs.
@ -220,9 +220,7 @@ bool ODFlacDecoder::ReadHeader()
//we want to use the native flac type for quick conversion.
/* (sampleFormat)
gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample);*/
if(mFile)
delete mFile;
mFile = new ODFLACFile(this);
mFile = std::make_unique<ODFLACFile>(this);
if (!mHandle.Open(mFName, wxT("rb"))) {
@ -261,15 +259,12 @@ bool ODFlacDecoder::ReadHeader()
ODFLACFile* ODFlacDecoder::GetFlacFile()
{
return mFile;
return mFile.get();
}
ODFlacDecoder::~ODFlacDecoder(){
if(mFile)
{
mFile->finish();
delete mFile;
}
}
///Creates an ODFileDecoder that decodes a file of filetype the subclass handles.
@ -303,12 +298,11 @@ ODFileDecoder* ODDecodeFlacTask::CreateFileDecoder(const wxString & fileName)
}
// Open the file for import
ODFlacDecoder *decoder = new ODFlacDecoder(fileName);
auto decoder = std::make_movable<ODFlacDecoder>(fileName);
*/
/*
bool success = decoder->Init();
if (!success) {
delete decoder;
return NULL;
}
*/

View File

@ -51,7 +51,7 @@ class ODDecodeFlacTask final : public ODDecodeTask
virtual ~ODDecodeFlacTask();
std::unique_ptr<ODTask> Clone() const override;
movable_ptr<ODTask> Clone() const override;
///Creates an ODFileDecoder that decodes a file of filetype the subclass handles.
ODFileDecoder* CreateFileDecoder(const wxString & fileName) override;
@ -119,7 +119,7 @@ public:
private:
friend class FLACImportFileHandle;
sampleFormat mFormat;
ODFLACFile *mFile;
std::unique_ptr<ODFLACFile> mFile;
ODLock mFlacFileLock;//for mFile;
wxFFile mHandle;
unsigned long mSampleRate;

View File

@ -32,7 +32,7 @@ static bool gPause=false; //to be loaded in and used with Pause/Resume before OD
/// a flag that is set if we have loaded some OD blockfiles from PCM.
static bool sHasLoadedOD=false;
ODManager* ODManager::pMan=NULL;
std::unique_ptr<ODManager> ODManager::pMan{};
//init the accessor function pointer - use the first time version of the interface fetcher
//first we need to typedef the function pointer type because the compiler doesn't support it in the raw
typedef ODManager* (*pfodman)();
@ -59,18 +59,36 @@ ODManager::ODManager()
mPause = gPause;
//must set up the queue condition
mQueueNotEmptyCond = new ODCondition(&mQueueNotEmptyCondLock);
mQueueNotEmptyCond = std::make_unique<ODCondition>(&mQueueNotEmptyCondLock);
}
//private destructor - DELETE with static method Quit()
ODManager::~ODManager()
{
mTerminateMutex.Lock();
mTerminate = true;
mTerminateMutex.Unlock();
//This while loop waits for ODTasks to finish and the DELETE removes all tasks from the Queue.
//This function is called from the main audacity event thread, so there should not be more requests for pMan
mTerminatedMutex.Lock();
while (!mTerminated)
{
mTerminatedMutex.Unlock();
wxThread::Sleep(200);
//signal the queue not empty condition since the ODMan thread will wait on the queue condition
mQueueNotEmptyCondLock.Lock();
mQueueNotEmptyCond->Signal();
mQueueNotEmptyCondLock.Unlock();
mTerminatedMutex.Lock();
}
mTerminatedMutex.Unlock();
//get rid of all the queues. The queues get rid of the tasks, so we don't worry abut them.
//nothing else should be running on OD related threads at this point, so we don't lock.
for(unsigned int i=0;i<mQueues.size();i++)
delete mQueues[i];
delete mQueueNotEmptyCond;
mQueues.clear();
}
///Adds a task to running queue. Thread-safe.
@ -124,8 +142,9 @@ void ODManager::RemoveTaskIfInQueue(ODTask* task)
///
///@param task the task to add
///@param lockMutex locks the mutexes if true (default). This function is used within other ODManager calls, which many need to set this to false.
void ODManager::AddNewTask(ODTask* task, bool lockMutex)
void ODManager::AddNewTask(movable_ptr<ODTask> &&mtask, bool lockMutex)
{
auto task = mtask.get();
ODWaveTrackTaskQueue* queue = NULL;
if(lockMutex)
@ -135,13 +154,13 @@ void ODManager::AddNewTask(ODTask* task, bool lockMutex)
//search for a task containing the lead track. wavetrack removal is threadsafe and bound to the mQueuesMutex
//note that GetWaveTrack is not threadsafe, but we are assuming task is not running on a different thread yet.
if(mQueues[i]->ContainsWaveTrack(task->GetWaveTrack(0)))
queue=mQueues[i];
queue = mQueues[i].get();
}
if(queue)
{
//Add it to the existing queue but keep the lock since this reference can be deleted.
queue->AddTask(task);
queue->AddTask(std::move(mtask));
if(lockMutex)
mQueuesMutex.Unlock();
}
@ -149,9 +168,9 @@ void ODManager::AddNewTask(ODTask* task, bool lockMutex)
{
//Make a NEW one, add it to the local track queue, and to the immediate running task list,
//since this task is definitely at the head
queue = new ODWaveTrackTaskQueue();
queue->AddTask(task);
mQueues.push_back(queue);
auto newqueue = make_movable<ODWaveTrackTaskQueue>();
newqueue->AddTask(std::move(mtask));
mQueues.push_back(std::move(newqueue));
if(lockMutex)
mQueuesMutex.Unlock();
@ -165,7 +184,7 @@ ODManager* ODManager::InstanceFirstTime()
gODInitedMutex.Lock();
if(!pMan)
{
pMan = new ODManager();
pMan.reset(safenew ODManager());
pMan->Init();
gManagerCreated = true;
}
@ -174,13 +193,13 @@ ODManager* ODManager::InstanceFirstTime()
//change the accessor function to use the quicker method.
Instance = &(ODManager::InstanceNormal);
return pMan;
return pMan.get();
}
//faster method of instance fetching once init is done
ODManager* ODManager::InstanceNormal()
{
return pMan;
return pMan.get();
}
bool ODManager::IsInstanceCreated()
@ -342,25 +361,7 @@ void ODManager::Quit()
{
if(IsInstanceCreated())
{
pMan->mTerminateMutex.Lock();
pMan->mTerminate = true;
pMan->mTerminateMutex.Unlock();
//This while loop waits for ODTasks to finish and the DELETE removes all tasks from the Queue.
//This function is called from the main audacity event thread, so there should not be more requests for pMan
pMan->mTerminatedMutex.Lock();
while(!pMan->mTerminated)
{
pMan->mTerminatedMutex.Unlock();
wxThread::Sleep(200);
//signal the queue not empty condition since the ODMan thread will wait on the queue condition
pMan->mQueueNotEmptyCond->Signal();
pMan->mTerminatedMutex.Lock();
}
pMan->mTerminatedMutex.Unlock();
delete pMan;
pMan.reset();
}
}
@ -396,7 +397,7 @@ void ODManager::MakeWaveTrackIndependent(WaveTrack* track)
{
if(mQueues[i]->ContainsWaveTrack(track))
{
owner = mQueues[i];
owner = mQueues[i].get();
break;
}
}
@ -425,11 +426,11 @@ bool ODManager::MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* mast
{
if(mQueues[i]->ContainsWaveTrack(masterTrack))
{
masterQueue = mQueues[i];
masterQueue = mQueues[i].get();
}
else if(mQueues[i]->ContainsWaveTrack(dependentTrack))
{
dependentQueue = mQueues[i];
dependentQueue = mQueues[i].get();
dependentIndex = i;
}
@ -450,7 +451,6 @@ bool ODManager::MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* mast
//finally remove the dependent track
mQueues.erase(mQueues.begin()+dependentIndex);
mQueuesMutex.Unlock();
delete dependentQueue; //note this locks the ODManager's current task queue.
return true;
}
@ -484,8 +484,7 @@ void ODManager::UpdateQueues()
{
//we need to release the lock on the queue vector before using the task vector's lock or we deadlock
//so get a temp.
ODWaveTrackTaskQueue* queue;
queue = mQueues[i];
ODWaveTrackTaskQueue* queue = mQueues[i].get();
AddTask(queue->GetFrontTask());
}
@ -494,7 +493,6 @@ void ODManager::UpdateQueues()
//if the queue is empty DELETE it.
if(mQueues[i]->IsEmpty())
{
delete mQueues[i];
mQueues.erase(mQueues.begin()+i);
i--;
}

View File

@ -62,7 +62,7 @@ class ODManager final
void DecrementCurrentThreads();
///Adds a wavetrack, creates a queue member.
void AddNewTask(ODTask* task, bool lockMutex=true);
void AddNewTask(movable_ptr<ODTask> &&mtask, bool lockMutex=true);
///Wakes the queue loop up by signalling its condition variable.
void SignalTaskQueueLoop();
@ -125,7 +125,8 @@ class ODManager final
//private constructor - Singleton.
ODManager();
//private constructor - DELETE with static method Quit()
virtual ~ODManager();
friend std::default_delete < ODManager > ;
~ODManager();
///Launches a thread for the manager and starts accepting Tasks.
void Init();
@ -136,10 +137,10 @@ class ODManager final
void UpdateQueues();
//instance
static ODManager* pMan;
static std::unique_ptr<ODManager> pMan;
//List of tracks and their active and inactive tasks.
std::vector<ODWaveTrackTaskQueue*> mQueues;
std::vector<movable_ptr<ODWaveTrackTaskQueue>> mQueues;
ODLock mQueuesMutex;
//List of current Task to do.
@ -169,7 +170,7 @@ class ODManager final
//for the queue not empty comdition
ODLock mQueueNotEmptyCondLock;
ODCondition* mQueueNotEmptyCond;
std::unique_ptr<ODCondition> mQueueNotEmptyCond;
#ifdef __WXMAC__

View File

@ -55,7 +55,7 @@ class ODTask /* not final */
virtual ~ODTask(){};
//clones everything except information about the tracks.
virtual std::unique_ptr<ODTask> Clone() const = 0;
virtual movable_ptr<ODTask> Clone() const = 0;
///Subclasses should override to return respective type.
virtual unsigned int GetODType(){return eODNone;}

View File

@ -16,6 +16,7 @@ tasks associated with a WaveTrack.
*//*******************************************************************/
#include "../Audacity.h"
#include "ODWaveTrackTaskQueue.h"
#include "ODTask.h"
#include "ODManager.h"
@ -31,8 +32,8 @@ ODWaveTrackTaskQueue::~ODWaveTrackTaskQueue()
{
mTasks[i]->TerminateAndBlock();//blocks if active.
//small chance we may have rea-added the task back into the queue from a diff thread. - so remove it if we have.
ODManager::Instance()->RemoveTaskIfInQueue(mTasks[i]);
delete mTasks[i];
ODManager::Instance()->RemoveTaskIfInQueue(mTasks[i].get());
mTasks[i].reset();
}
}
@ -100,10 +101,12 @@ void ODWaveTrackTaskQueue::AddWaveTrack(WaveTrack* track)
mTracksMutex.Unlock();
}
void ODWaveTrackTaskQueue::AddTask(ODTask* task)
void ODWaveTrackTaskQueue::AddTask(movable_ptr<ODTask> &&mtask)
{
ODTask *task = mtask.get();
mTasksMutex.Lock();
mTasks.push_back(task);
mTasks.push_back(std::move(mtask));
mTasksMutex.Unlock();
//take all of the tracks in the task.
@ -172,7 +175,7 @@ void ODWaveTrackTaskQueue::MakeWaveTrackIndependent(WaveTrack* track)
mTasksMutex.Unlock();
//AddNewTask locks the m_queuesMutex which is already locked by ODManager::MakeWaveTrackIndependent,
//so we pass a boolean flag telling it not to lock again.
ODManager::Instance()->AddNewTask(task.release(), false);
ODManager::Instance()->AddNewTask(std::move(task), false);
mTasksMutex.Lock();
}
mTasksMutex.Unlock();
@ -256,7 +259,7 @@ ODTask* ODWaveTrackTaskQueue::GetTask(size_t x)
ODTask* ret = NULL;
mTasksMutex.Lock();
if (x < mTasks.size())
ret = mTasks[x];
ret = mTasks[x].get();
mTasksMutex.Unlock();
return ret;
}
@ -304,7 +307,6 @@ void ODWaveTrackTaskQueue::RemoveFrontTask()
if(mTasks.size())
{
//wait for the task to stop running.
delete mTasks[0];
mTasks.erase(mTasks.begin());
}
mTasksMutex.Unlock();
@ -317,7 +319,7 @@ ODTask* ODWaveTrackTaskQueue::GetFrontTask()
if(mTasks.size())
{
mTasksMutex.Unlock();
return mTasks[0];
return mTasks[0].get();
}
mTasksMutex.Unlock();
return NULL;

View File

@ -22,6 +22,7 @@ tasks associated with a WaveTrack.
#ifndef __AUDACITY_ODWAVETRACKTASKQUEUE__
#define __AUDACITY_ODWAVETRACKTASKQUEUE__
#include "../MemoryX.h"
#include <vector>
#include "ODTaskThread.h"
#include <wx/wx.h>
@ -71,7 +72,7 @@ class ODWaveTrackTaskQueue final
int GetNumWaveTracks();
///Add a task to the queue.
void AddTask(ODTask* task);
void AddTask(movable_ptr<ODTask> &&mtask);
//returns true if either tracks or tasks are empty
bool IsEmpty();
@ -105,7 +106,7 @@ class ODWaveTrackTaskQueue final
ODLock mTracksMutex;
///the list of tasks associated with the tracks. This class owns these tasks.
std::vector<ODTask*> mTasks;
std::vector<movable_ptr<ODTask>> mTasks;
ODLock mTasksMutex;
};