From 0fac236e9ac2b638cc33133bea1478b9a78cdd8f Mon Sep 17 00:00:00 2001 From: mchinen Date: Mon, 19 Jul 2010 13:25:52 +0000 Subject: [PATCH] Fix whitespace and comments in ODComputeSummaryTask and ODManager --- src/ondemand/ODComputeSummaryTask.cpp | 113 +++++++++----------- src/ondemand/ODComputeSummaryTask.h | 12 --- src/ondemand/ODManager.cpp | 148 ++++++++++++-------------- src/ondemand/ODManager.h | 113 +++++++++----------- 4 files changed, 167 insertions(+), 219 deletions(-) diff --git a/src/ondemand/ODComputeSummaryTask.cpp b/src/ondemand/ODComputeSummaryTask.cpp index 6f1d6e7e3..ff7c97957 100644 --- a/src/ondemand/ODComputeSummaryTask.cpp +++ b/src/ondemand/ODComputeSummaryTask.cpp @@ -31,33 +31,29 @@ ODComputeSummaryTask::ODComputeSummaryTask() mMaxBlockFiles = 0; mComputedBlockFiles = 0; mHasUpdateRan=false; - } - + ODTask* ODComputeSummaryTask::Clone() { ODComputeSummaryTask* clone = new ODComputeSummaryTask; clone->mDemandSample=GetDemandSample(); return clone; - } ///releases memory that the ODTask owns. Subclasses should override. void ODComputeSummaryTask::Terminate() { - //The terminate cblock won't allow DoSomeInternal and this method to be run async, so this is thread-safe - - //we are going to take things out of the array. But first deref them since we ref them when we put them in. - + //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;iDeref(); mBlockFiles.clear(); mBlockFilesMutex.Unlock(); -} - -///Computes and writes the data for one BlockFile if it still has a refcount. +} + +///Computes and writes the data for one BlockFile if it still has a refcount. void ODComputeSummaryTask::DoSomeInternal() { if(mBlockFiles.size()<=0) @@ -67,19 +63,18 @@ void ODComputeSummaryTask::DoSomeInternal() mPercentCompleteMutex.Unlock(); return; } - + ODPCMAliasBlockFile* bf; sampleCount blockStartSample; sampleCount blockEndSample; bool success =false; - - + mBlockFilesMutex.Lock(); for(size_t i=0; i < mWaveTracks.size() && mBlockFiles.size();i++) { bf = mBlockFiles[0]; - - //first check to see if the ref count is at least 2. It should have one + + //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) @@ -96,19 +91,18 @@ void ODComputeSummaryTask::DoSomeInternal() //because now there is less work to do. 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()); - - //This is a bit of a convenience in case someone tries to terminate the task by closing the trackpanel or window. - //ODComputeSummaryTask::Terminate() uses this lock to remove everything, and we don't want it to wait since the UI is being blocked. + + //This is a bit of a convenience in case someone tries to terminate the task by closing the trackpanel or window. + //ODComputeSummaryTask::Terminate() uses this lock to remove everything, and we don't want it to wait since the UI is being blocked. mBlockFilesMutex.Unlock(); wxThread::This()->Yield(); mBlockFilesMutex.Lock(); - - + //upddate the gui for all associated blocks. It doesn't matter that we're hitting more wavetracks then we should //because this loop runs a number of times equal to the number of tracks, they probably are getting processed in //the next iteration at the same sample window. @@ -119,28 +113,26 @@ void ODComputeSummaryTask::DoSomeInternal() mWaveTracks[i]->AddInvalidRegion(blockStartSample,blockEndSample); } mWaveTrackMutex.Unlock(); - - - } - + } + mBlockFilesMutex.Unlock(); - + //update percentage complete. CalculatePercentComplete(); } ///compute the next time we should take a break in terms of overall percentage. -///We want to do a constant number of blockfiles. +///We want to do a constant number of blockfiles. float ODComputeSummaryTask::ComputeNextWorkUntilPercentageComplete() { if(mMaxBlockFiles==0) return 1.0; - + float nextPercent; mPercentCompleteMutex.Lock(); nextPercent=mPercentComplete + ((float)kNumBlockFilesPerDoSome/(mMaxBlockFiles+1)); mPercentCompleteMutex.Unlock(); - + return nextPercent; } @@ -149,7 +141,7 @@ void ODComputeSummaryTask::MarkUpdateRan() mHasUpdateRanMutex.Lock(); mHasUpdateRan=true; mHasUpdateRanMutex.Unlock(); -} +} bool ODComputeSummaryTask::HasUpdateRan() { @@ -172,14 +164,14 @@ void ODComputeSummaryTask::CalculatePercentComplete() mPercentCompleteMutex.Unlock(); } -///by default creates the order of the wavetrack to load. +///creates the order of the wavetrack to load. +///by default left to right, or frome the point the user has clicked. void ODComputeSummaryTask::Update() { - std::vector tempBlocks; - + mWaveTrackMutex.Lock(); - + for(size_t j=0;jGetClipIterator(); - + while(node) { clip = node->GetData(); seq = clip->GetSequence(); - //This lock may be way too big since the whole file is one sequence. + //This lock may be way too big since the whole file is one sequence. //TODO: test for large files and find a way to break it down. seq->LockDeleteUpdateMutex(); - + //See Sequence::Delete() for why need this for now.. - //We don't need the mBlockFilesMutex here because it is only for the vector list. - //These are existing blocks, and its wavetrack or blockfiles won't be deleted because - //of the respective mWaveTrackMutex lock and LockDeleteUpdateMutex() call. + //We don't need the mBlockFilesMutex here because it is only for the vector list. + //These are existing blocks, and its wavetrack or blockfiles won't be deleted because + //of the respective mWaveTrackMutex lock and LockDeleteUpdateMutex() call. blocks = clip->GetSequenceBlockArray(); int i; int insertCursor; - + insertCursor =0;//OD TODO:see if this works, removed from inner loop (bfore was n*n) - + for(i=0; i<(int)blocks->GetCount(); i++) { //if there is data but no summary, this blockfile needs summarizing. @@ -216,59 +208,59 @@ void ODComputeSummaryTask::Update() blocks->Item(i)->f->Ref(); ((ODPCMAliasBlockFile*)blocks->Item(i)->f)->SetStart(blocks->Item(i)->start); ((ODPCMAliasBlockFile*)blocks->Item(i)->f)->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate())); - + //these will always be linear within a sequence-lets take advantage of this by keeping a cursor. - while(insertCursor<(int)tempBlocks.size()&& - (sampleCount)(tempBlocks[insertCursor]->GetStart()+tempBlocks[insertCursor]->GetClipOffset()) < + while(insertCursor<(int)tempBlocks.size()&& + (sampleCount)(tempBlocks[insertCursor]->GetStart()+tempBlocks[insertCursor]->GetClipOffset()) < (sampleCount)(((ODPCMAliasBlockFile*)blocks->Item(i)->f)->GetStart()+((ODPCMAliasBlockFile*)blocks->Item(i)->f)->GetClipOffset())) insertCursor++; - + tempBlocks.insert(tempBlocks.begin()+insertCursor++,(ODPCMAliasBlockFile*)blocks->Item(i)->f); } - } + } seq->UnlockDeleteUpdateMutex(); node = node->GetNext(); } } } mWaveTrackMutex.Unlock(); - + //get the new order. mBlockFilesMutex.Lock(); OrderBlockFiles(tempBlocks); mBlockFilesMutex.Unlock(); - + MarkUpdateRan(); } -///Orders the input as either On-Demand or default layered order. +///Computes the summary calculation queue order of the blockfiles void ODComputeSummaryTask::OrderBlockFiles(std::vector &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;iDeref(); mBlockFiles.clear(); - //TODO:order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs) + //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 - //(which the user sets by clicking.) + //(which the user sets by clicking.) //Note that this code assumes that the array is sorted in time. - + //find the startpoint - sampleCount processStartSample = GetDemandSample(); + sampleCount processStartSample = GetDemandSample(); for(int i= ((int)unorderedBlocks.size())-1;i>= 0;i--) { //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. + //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) { //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. - if(mBlockFiles.size() && - unorderedBlocks[i]->GetGlobalEnd() >= processStartSample && - ( mBlockFiles[0]->GetGlobalEnd() < processStartSample || + if(mBlockFiles.size() && + unorderedBlocks[i]->GetGlobalEnd() >= processStartSample && + ( mBlockFiles[0]->GetGlobalEnd() < processStartSample || unorderedBlocks[i]->GetGlobalStart() <= mBlockFiles[0]->GetGlobalStart()) ) { @@ -289,5 +281,4 @@ void ODComputeSummaryTask::OrderBlockFiles(std::vector &un unorderedBlocks[i]->Deref(); } } - -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/ondemand/ODComputeSummaryTask.h b/src/ondemand/ODComputeSummaryTask.h index 7834965f0..e8bc894ca 100644 --- a/src/ondemand/ODComputeSummaryTask.h +++ b/src/ondemand/ODComputeSummaryTask.h @@ -16,9 +16,6 @@ updating the ODPCMAliasBlockFile and the GUI of the newly available data. *//*******************************************************************/ - - - #ifndef __AUDACITY_ODComputeSummaryTask__ #define __AUDACITY_ODComputeSummaryTask__ @@ -54,10 +51,8 @@ class ODComputeSummaryTask:public ODTask ///releases memory that the ODTask owns. Subclasses should override. virtual void Terminate(); - protected: - ///recalculates the percentage complete. virtual void CalculatePercentComplete(); @@ -78,17 +73,10 @@ 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 mBlockFiles; - - int mMaxBlockFiles; int mComputedBlockFiles; - - - ODLock mHasUpdateRanMutex; bool mHasUpdateRan; - - }; #endif diff --git a/src/ondemand/ODManager.cpp b/src/ondemand/ODManager.cpp index dc279c2ca..21673e484 100644 --- a/src/ondemand/ODManager.cpp +++ b/src/ondemand/ODManager.cpp @@ -10,7 +10,7 @@ \file ODManager.cpp \brief Singleton ODManager class. Is the bridge between client side -ODTask requests and internals. +ODTask requests and internals. *//*******************************************************************/ @@ -28,11 +28,11 @@ ODTask requests and internals. ODLock gODInitedMutex; bool gManagerCreated=false; bool gPause=false; //to be loaded in and used with Pause/Resume before ODMan init. -/// a flag that is set if we have loaded some OD blockfiles from PCM. +/// a flag that is set if we have loaded some OD blockfiles from PCM. bool sHasLoadedOD=false; -ODManager* ODManager::pMan=NULL; -//init the accessor function pointer - use the first time version of the interface fetcher +ODManager* ODManager::pMan=NULL; +//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)(); pfodman ODManager::Instance = &(ODManager::InstanceFirstTime); @@ -42,7 +42,7 @@ ODLock sLibSndFileMutex; DEFINE_EVENT_TYPE(EVT_ODTASK_UPDATE) -//using this with wxStringArray::Sort will give you a list that +//using this with wxStringArray::Sort will give you a list that //is alphabetical, without depending on case. If you use the //default sort, you will get strings with 'R' before 'a', because it is in caps. int CompareNoCaseFileName(const wxString& first, const wxString& second) @@ -67,7 +67,7 @@ ODManager::ODManager() mTerminate = false; mTerminated = false; mPause= gPause; - + //must set up the queue condition mQueueNotEmptyCond = new ODCondition(&mQueueNotEmptyCondLock); } @@ -83,17 +83,15 @@ ODManager::~ODManager() delete mQueueNotEmptyCond; } - - ///Adds a task to running queue. Thread-safe. void ODManager::AddTask(ODTask* task) { mTasksMutex.Lock(); mTasks.push_back(task); mTasksMutex.Unlock(); - //signal the queue not empty condition. + //signal the queue not empty condition. bool paused; - + mPauseLock.Lock(); paused=mPause; mPauseLock.Unlock(); @@ -103,13 +101,12 @@ void ODManager::AddTask(ODTask* task) if(!paused) mQueueNotEmptyCond->Signal(); mQueueNotEmptyCondLock.Unlock(); - } void ODManager::SignalTaskQueueLoop() { bool paused; - + mPauseLock.Lock(); paused=mPause; mPauseLock.Unlock(); @@ -154,7 +151,7 @@ void ODManager::AddNewTask(ODTask* task, bool lockMutex) if(mQueues[i]->ContainsWaveTrack(task->GetWaveTrack(0))) queue=mQueues[i]; } - + if(queue) { //Add it to the existing queue but keep the lock since this reference can be deleted. @@ -171,12 +168,11 @@ void ODManager::AddNewTask(ODTask* task, bool lockMutex) mQueues.push_back(queue); if(lockMutex) mQueuesMutex.Unlock(); - + AddTask(task); - } } - + //that switches out the mutex/null check. ODManager* ODManager::InstanceFirstTime() { @@ -188,10 +184,10 @@ ODManager* ODManager::InstanceFirstTime() gManagerCreated = true; } gODInitedMutex.Unlock(); - + //change the accessor function to use the quicker method. Instance = &(ODManager::InstanceNormal); - + return pMan; } @@ -215,15 +211,15 @@ void ODManager::Init() { mCurrentThreads = 0; mMaxThreads = 5; - + // wxLogDebug(wxT("Initializing ODManager...Creating manager thread\n")); ODManagerHelperThread* startThread = new ODManagerHelperThread; - + // startThread->SetPriority(0);//default of 50. startThread->Create(); // printf("starting thread from init\n"); startThread->Run(); - + // printf("started thread from init\n"); //destruction of thread is taken care of by thread library } @@ -237,12 +233,12 @@ void ODManager::DecrementCurrentThreads() ///Main loop for managing threads and tasks. void ODManager::Start() -{ +{ ODTaskThread* thread; bool tasksInArray; bool paused; int numQueues=0; - + mNeedsDraw=0; //wxLog calls not threadsafe. are printfs? thread-messy for sure, but safe? @@ -254,54 +250,52 @@ void ODManager::Start() { mTerminateMutex.Unlock(); // printf("ODManager thread running \n"); - + //we should look at our WaveTrack queues to see if we can process a new task to the running queue. UpdateQueues(); - + //start some threads if necessary - + mTasksMutex.Lock(); tasksInArray = mTasks.size()>0; mTasksMutex.Unlock(); mCurrentThreadsMutex.Lock(); - + mPauseLock.Lock(); paused=mPause; mPauseLock.Unlock(); - + // keep adding tasks if there is work to do, up to the limit. while(!paused && tasksInArray && (mCurrentThreads < mMaxThreads)) { mCurrentThreads++; mCurrentThreadsMutex.Unlock(); - //remove the head - + //detach a new thread. thread = new ODTaskThread(mTasks[0]);//task); - -// thread->SetPriority(10);//default is 50. + //thread->SetPriority(10);//default is 50. thread->Create(); thread->Run(); - - mTasks.erase(mTasks.begin()); + + mTasks.erase(mTasks.begin()); tasksInArray = mTasks.size()>0; - + mTasksMutex.Unlock(); - + mCurrentThreadsMutex.Lock(); } mCurrentThreadsMutex.Unlock(); - //use a conditon variable to block here instead of a sleep. + //use a conditon variable to block here instead of a sleep. - // JKC: If there are no tasks ready to run, or we're paused then + // JKC: If there are no tasks ready to run, or we're paused then // we wait for there to be tasks in the queue. mQueueNotEmptyCondLock.Lock(); if( (!tasksInArray) || paused) mQueueNotEmptyCond->Wait(); - mQueueNotEmptyCondLock.Unlock(); - - //if there is some ODTask running, then there will be something in the queue. If so then redraw to show progress + mQueueNotEmptyCondLock.Unlock(); + + //if there is some ODTask running, then there will be something in the queue. If so then redraw to show progress mQueuesMutex.Lock(); mNeedsDraw += mQueues.size()>0?1:0; numQueues=mQueues.size(); @@ -319,15 +313,15 @@ void ODManager::Start() if(proj) proj->AddPendingEvent( event ); AudacityProject::AllProjectsDeleteUnlock(); - } + } mTerminateMutex.Lock(); } mTerminateMutex.Unlock(); - + mTerminatedMutex.Lock(); mTerminated=true; mTerminatedMutex.Unlock(); - + //wxLogDebug Not thread safe. //printf("ODManager thread terminating\n"); @@ -343,7 +337,7 @@ void ODManager::Pause(bool pause) pMan->mPauseLock.Lock(); pMan->mPause = pause; pMan->mPauseLock.Unlock(); - + //we should check the queue again. pMan->mQueueNotEmptyCondLock.Lock(); pMan->mQueueNotEmptyCond->Signal(); @@ -367,13 +361,15 @@ void ODManager::Quit() 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->mQueueNotEmptyCondLock.Lock(); pMan->mQueueNotEmptyCond->Signal(); @@ -382,15 +378,11 @@ void ODManager::Quit() pMan->mTerminatedMutex.Lock(); } pMan->mTerminatedMutex.Unlock(); - - delete pMan; - //The above 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 } } - -///removes a wavetrack and notifies its associated tasks to stop using its reference. + +///removes a wavetrack and notifies its associated tasks to stop using its reference. void ODManager::RemoveWaveTrack(WaveTrack* track) { mQueuesMutex.Lock(); @@ -411,7 +403,7 @@ void ODManager::ReplaceWaveTrack(WaveTrack* oldTrack,WaveTrack* newTrack) mQueues[i]->ReplaceWaveTrack(oldTrack,newTrack); } mQueuesMutex.Unlock(); -} +} ///if it shares a queue/task, creates a new queue/task for the track, and removes it from any previously existing tasks. void ODManager::MakeWaveTrackIndependent(WaveTrack* track) @@ -430,24 +422,22 @@ void ODManager::MakeWaveTrackIndependent(WaveTrack* track) owner->MakeWaveTrackIndependent(track); mQueuesMutex.Unlock(); - } ///attach the track in question to another, already existing track's queues and tasks. Remove the task/tracks. ///only works if both tracks exist. Sets needODUpdate flag for the task. This is complicated and will probably need ///better design in the future. -///@return returns success. Some ODTask conditions require that the tasks finish before merging. -///e.g. they have different effects being processed at the same time. +///@return returns success. Some ODTask conditions require that the tasks finish before merging. +///e.g. they have different effects being processed at the same time. bool ODManager::MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* masterTrack) { - - //First, check to see if the task lists are mergeable. If so, we can simply add this track to the other task and queue, + //First, check to see if the task lists are mergeable. If so, we can simply add this track to the other task and queue, //then delete this one. ODWaveTrackTaskQueue* masterQueue=NULL; ODWaveTrackTaskQueue* dependentQueue=NULL; unsigned int dependentIndex; bool canMerge = false; - + mQueuesMutex.Lock(); for(unsigned int i=0;iCanMergeWith(dependentQueue); - //otherwise we need to let dependentTrack's queue live on. We'll have to wait till the conflicting tasks are done. if(!canMerge) - { + { mQueuesMutex.Unlock(); return false; - } + } //then we add dependentTrack to the masterTrack's queue - this will allow future ODScheduling to affect them together. //this sets the NeedODUpdateFlag since we don't want the head task to finish without haven't dealt with the depednent masterQueue->MergeWaveTrack(dependentTrack); - + //finally remove the dependent track mQueues.erase(mQueues.begin()+dependentIndex); mQueuesMutex.Unlock(); @@ -495,9 +484,8 @@ void ODManager::DemandTrackUpdate(WaveTrack* track, double seconds) mQueues[i]->DemandTrackUpdate(track,seconds); } mQueuesMutex.Unlock(); - } - + ///remove tasks from ODWaveTrackTaskQueues that have been done. Schedules new ones if they exist ///Also remove queues that have become empty. void ODManager::UpdateQueues() @@ -505,7 +493,6 @@ void ODManager::UpdateQueues() mQueuesMutex.Lock(); for(unsigned int i=0;iIsFrontTaskComplete()) { //this should delete and remove the front task instance. @@ -517,11 +504,11 @@ void ODManager::UpdateQueues() //so get a temp. ODWaveTrackTaskQueue* queue; queue = mQueues[i]; - + AddTask(queue->GetFrontTask()); } } - + //if the queue is empty delete it. if(mQueues[i]->IsEmpty()) { @@ -531,25 +518,24 @@ void ODManager::UpdateQueues() } } mQueuesMutex.Unlock(); - } -//static -///sets a flag that is set if we have loaded some OD blockfiles from PCM. +//static +///sets a flag that is set if we have loaded some OD blockfiles from PCM. void ODManager::MarkLoadedODFlag() { sHasLoadedOD = true; -} - -//static -///resets a flag that is set if we have loaded some OD blockfiles from PCM. +} + +//static +///resets a flag that is set if we have loaded some OD blockfiles from PCM. void ODManager::UnmarkLoadedODFlag() { sHasLoadedOD = false; } - -//static -///returns a flag that is set if we have loaded some OD blockfiles from PCM. + +//static +///returns a flag that is set if we have loaded some OD blockfiles from PCM. bool ODManager::HasLoadedODFlag() { return sHasLoadedOD; @@ -576,12 +562,12 @@ float ODManager::GetOverallPercentComplete() total+=mQueues[i]->GetFrontTask()->PercentComplete(); } mQueuesMutex.Unlock(); - + //avoid div by zero and be thread smart. int totalTasks = GetTotalNumTasks(); return (float) total/(totalTasks>0?totalTasks:1); } - + ///Get Total Number of Tasks. int ODManager::GetTotalNumTasks() { diff --git a/src/ondemand/ODManager.h b/src/ondemand/ODManager.h index cd2ae7f26..c5f50650e 100644 --- a/src/ondemand/ODManager.h +++ b/src/ondemand/ODManager.h @@ -3,7 +3,7 @@ Audacity: A Digital Audio Editor ODManager.h - + Created by Michael Chinen (mchinen) on 6/8/08 Audacity(R) is copyright (c) 1999-2008 Audacity Team. License: GPL v2. See License.txt. @@ -11,39 +11,32 @@ ******************************************************************//** \class ODManager -\brief A singleton that manages currently running Tasks on an arbitrary +\brief A singleton that manages currently running Tasks on an arbitrary number of threads. *//*******************************************************************/ - - - - #ifndef __AUDACITY_ODMANAGER__ #define __AUDACITY_ODMANAGER__ + #include #include "ODTask.h" #include "ODTaskThread.h" #include - #include #ifdef __WXMAC__ - // On Mac OS X, it's better not to use the wxThread class. // We use our own implementation based on pthreads instead. - #include #include #endif //__WXMAC__ - DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_ODTASK_UPDATE, -1) ///wxstring compare function for sorting case, which is needed to load correctly. int CompareNoCaseFileName(const wxString& first, const wxString& second); -/// A singleton that manages currently running Tasks on an arbitrary +/// A singleton that manages currently running Tasks on an arbitrary /// number of threads. class WaveTrack; class ODWaveTrackTaskQueue; @@ -57,61 +50,61 @@ class ODManager static ODManager* InstanceFirstTime(); ///Gets the singleton instance static ODManager* InstanceNormal(); - + ///Kills the ODMananger Thread. - static void Quit(); - + static void Quit(); + ///changes the tasks associated with this Waveform to process the task from a different point in the track void DemandTrackUpdate(WaveTrack* track, double seconds); - + ///Reduces the count of current threads running. Meant to be called when ODTaskThreads end in their own threads. Thread-safe. void DecrementCurrentThreads(); - - ///Adds a wavetrack, creates a queue member. + + ///Adds a wavetrack, creates a queue member. void AddNewTask(ODTask* task, bool lockMutex=true); - + ///Wakes the queue loop up by signalling its condition variable. void SignalTaskQueueLoop(); - - ///removes a wavetrack and notifies its associated tasks to stop using its reference. + + ///removes a wavetrack and notifies its associated tasks to stop using its reference. void RemoveWaveTrack(WaveTrack* track); - + ///if it shares a queue/task, creates a new queue/task for the track, and removes it from any previously existing tasks. void MakeWaveTrackIndependent(WaveTrack* track); - + ///attach the track in question to another, already existing track's queues and tasks. Remove the task/tracks. ///Returns success if it was possible.. Some ODTask conditions make it impossible until the Tasks finish. bool MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* masterTrack); - + ///replace the wavetrack whose wavecache the gui watches for updates - void ReplaceWaveTrack(WaveTrack* oldTrack,WaveTrack* newTrack); - + void ReplaceWaveTrack(WaveTrack* oldTrack,WaveTrack* newTrack); + ///Adds a task to the running queue. Threas-safe. void AddTask(ODTask* task); - + void RemoveTaskIfInQueue(ODTask* task); - - ///sets a flag that is set if we have loaded some OD blockfiles from PCM. + + ///sets a flag that is set if we have loaded some OD blockfiles from PCM. static void MarkLoadedODFlag(); - - ///resets a flag that is set if we have loaded some OD blockfiles from PCM. + + ///resets a flag that is set if we have loaded some OD blockfiles from PCM. static void UnmarkLoadedODFlag(); - - ///returns a flag that is set if we have loaded some OD blockfiles from PCM. + + ///returns a flag that is set if we have loaded some OD blockfiles from PCM. static bool HasLoadedODFlag(); - + ///returns whether or not the singleton instance was created yet static bool IsInstanceCreated(); - + ///fills in the status bar message for a given track void FillTipForWaveTrack( WaveTrack * t, const wxChar ** ppTip ); - + ///Gets the total percent complete for all tasks combined. float GetOverallPercentComplete(); - + ///Get Total Number of Tasks. int GetTotalNumTasks(); - + //Pause/unpause all OD Tasks. Does not occur immediately. static void Pause(bool pause = true); static void Resume(); @@ -120,7 +113,7 @@ class ODManager static void UnlockLibSndFileMutex(); - + protected: //private constructor - Singleton. ODManager(); @@ -131,47 +124,46 @@ class ODManager ///Start the main loop for the manager. void Start(); - + ///Remove references in our array to Tasks that have been completed/Schedule new ones void UpdateQueues(); - + //instance static ODManager* pMan; - + //List of tracks and their active and inactive tasks. std::vector mQueues; ODLock mQueuesMutex; - + //List of current Task to do. std::vector mTasks; //mutex for above variable ODLock mTasksMutex; - + //global pause switch for OD volatile bool mPause; ODLock mPauseLock; volatile int mNeedsDraw; - + ///Number of threads currently running. Accessed thru multiple threads volatile int mCurrentThreads; //mutex for above variable ODLock mCurrentThreadsMutex; - - + ///Maximum number of threads allowed out. int mMaxThreads; - + volatile bool mTerminate; ODLock mTerminateMutex; - + volatile bool mTerminated; ODLock mTerminatedMutex; - + //for the queue not empty comdition ODLock mQueueNotEmptyCondLock; ODCondition* mQueueNotEmptyCond; - + #ifdef __WXMAC__ // On Mac OS X, it's better not to use the wxThread class. @@ -201,34 +193,30 @@ class ODManagerHelperThread { ODManagerHelperThread *th = (ODManagerHelperThread *)p; /* return (void *) */th->Entry(); } - + ///Specifies the priority the thread will run at. Currently doesn't work. ///@param priority value from 0 (min priority) to 100 (max priority) void SetPriority(int priority) { mPriority=priority; } - + void Run() { pthread_create(&mThread, NULL, callback, this); } private: bool mDestroy; pthread_t mThread; - int mPriority; - }; - #else - - class ODManagerHelperThread : public wxThread + class ODManagerHelperThread : public wxThread { public: ///Constructs a ODTaskThread - ///@param task the task to be launched as an + ///@param task the task to be launched as an ODManagerHelperThread(): wxThread(){} - + protected: ///Executes a part of the task void *Entry() @@ -236,14 +224,9 @@ class ODManagerHelperThread { ODManager::Instance()->Start(); return NULL; } - + }; - #endif //__WXMAC__ - - - - }; #endif