示例#1
0
///Main loop for managing threads and tasks.
void ODManager::Start()
{   

   ODTask* task;
   ODTaskThread* thread;
   bool tasksInArray;

   //wxLog calls not threadsafe.  are printfs?  thread-messy for sure, but safe?
   printf("ODManager thread strating \n");
   //TODO: Figure out why this has no effect at all.
   //wxThread::This()->SetPriority(30);
   mTerminateMutex.Lock();
   while(!mTerminate)
   {
      mTerminateMutex.Unlock();
      
      //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();
      
      while( tasksInArray&& mCurrentThreads < mMaxThreads)
      {
         mCurrentThreads++;
         mCurrentThreadsMutex.Unlock();
         //remove the head
         mTasksMutex.Lock();
         task = mTasks[0];
         
         //the thread will add it back to the array if the job is not yet done at the end of the thread's run.  
         mTasks.erase(mTasks.begin());  
         mTasksMutex.Unlock();
         
         //detach a new thread.
         thread = new ODTaskThread(task);
         
//         thread->SetPriority(10);//default is 50.
         thread->Create();
         thread->Run();
         
         mTasksMutex.Lock();
         tasksInArray = mTasks.size()>0;
         mTasksMutex.Unlock();
         
         mCurrentThreadsMutex.Lock();
      }

      mCurrentThreadsMutex.Unlock();
      wxThread::Sleep(200);
//wxSleep can't be called from non-main thread.
//      ::wxMilliSleep(250);
      mTerminateMutex.Lock();
      
      //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;
      mQueuesMutex.Unlock();
//      
//      //TODO:this is a little excessive, in the future only redraw some, and if possible only the Tracks on the trackpanel..
      if(mNeedsDraw > 18)
      {
         mNeedsDraw=0;
         wxCommandEvent event( wxEVT_ODTASK_UPDATE );
         AudacityProject::AllProjectsDeleteLock();
         AudacityProject* proj = GetActiveProject();
         if(proj)
            proj->AddPendingEvent( event );
         AudacityProject::AllProjectsDeleteUnlock();
      }   
   }
   mTerminateMutex.Unlock();
   
   
   //wxLogDebug Not thread safe.
   //printf("ODManager thread terminating\n");

}
示例#2
0
///Do a modular part of the task.  For example, if the task is to load the entire file, load one BlockFile.
///Relies on DoSomeInternal(), which is the subclasses must implement.
///@param amountWork the percent amount of the total job to do.  1.0 represents the entire job.  the default of 0.0
/// will do the smallest unit of work possible
void ODTask::DoSome(float amountWork)
{
   mBlockUntilTerminateMutex.Lock();

   printf("%s %i subtask starting on new thread with priority\n", GetTaskName(),GetTaskNumber());

   mDoingTask=mTaskStarted=true;
   
   float workUntil = amountWork+PercentComplete();
   
   if(workUntil<PercentComplete())
      workUntil = PercentComplete();
   
   //check periodically to see if we should exit.
   mTerminateMutex.Lock();
   if(mTerminate)
   {
      mBlockUntilTerminateMutex.Unlock();
      mTerminateMutex.Unlock();
      return;
   }  
   mTerminateMutex.Unlock();

   Update();   
   
   //Do Some of the task.
   
   mTerminateMutex.Lock();
   while(PercentComplete() < workUntil && PercentComplete() < 1.0 && !mTerminate)
   {
      wxThread::This()->Yield();
      //release within the loop so we can cut the number of iterations short
      mTerminateMutex.Unlock();
      //TODO: check to see if ondemand has been called
      if(false)
         ODUpdate();
      DoSomeInternal();
      
      //But add the mutex lock back before we check the value again.
      mTerminateMutex.Lock();
   }
   mTerminateMutex.Unlock();
   mDoingTask=false;
   
   mTerminateMutex.Lock();
   //if it is not done, put it back onto the ODManager queue.
   if(!IsComplete() && !mTerminate)
   {
      ODManager::Instance()->AddTask(this);
      printf("%s %i is %f done\n", GetTaskName(),GetTaskNumber(),PercentComplete());
   }
   else
   {
      wxCommandEvent event( wxEVT_ODTASK_COMPLETE );
      AudacityProject::AllProjectsDeleteLock();
      AudacityProject* proj = GetActiveProject();
      if(proj)
         proj->AddPendingEvent( event );
      AudacityProject::AllProjectsDeleteUnlock();

      printf("%s %i complete\n", GetTaskName(),GetTaskNumber());
   }
   mTerminateMutex.Unlock();
   mBlockUntilTerminateMutex.Unlock();
   
}