void ODManager::AddTaskToWaveTrack(ODTask* task, WaveTrack* track) { ODWaveTrackTaskQueue* queue = NULL; mQueuesMutex.Lock(); for(int i=0;i<mQueues.size();i++) { if(mQueues[i]->ContainsWaveTrack(track)) queue=mQueues[i]; } if(queue) { //Add it to the existing queue but keep the lock since this reference can be deleted. queue->AddTask(task); mQueuesMutex.Unlock(); } else { //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(track); queue->AddTask(task); mQueues.push_back(queue); mQueuesMutex.Unlock(); AddTask(task); } }
///remove tasks from ODWaveTrackTaskQueues that have been done. Schedules NEW ones if they exist ///Also remove queues that have become empty. void ODManager::UpdateQueues() { mQueuesMutex.Lock(); for(unsigned int i=0;i<mQueues.size();i++) { if(mQueues[i]->IsFrontTaskComplete()) { //this should DELETE and remove the front task instance. mQueues[i]->RemoveFrontTask(); //schedule next. if(!mQueues[i]->IsEmpty()) { //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 = mQueues[i].get(); AddTask(queue->GetFrontTask()); } } //if the queue is empty DELETE it. if(mQueues[i]->IsEmpty()) { mQueues.erase(mQueues.begin()+i); i--; } } 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() { mQueuesMutex.Lock(); for(int i=0;i<mQueues.size();i++) { if(mQueues[i]->IsFrontTaskComplete()) { mQueues[i]->RemoveFrontTask(); //schedule next. if(!mQueues[i]->IsEmpty()) { //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]; mQueuesMutex.Unlock(); AddTask(queue->GetFrontTask()); mQueuesMutex.Lock(); } } //if the queue is empty delete it. if(mQueues[i]->IsEmpty()) { delete mQueues[i]; mQueues.erase(mQueues.begin()+i); i--; } } mQueuesMutex.Unlock(); }
///Adds a NEW task to the queue. Creates a queue if the tracks associated with the task is not in the list /// ///@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(movable_ptr<ODTask> &&mtask, bool lockMutex) { auto task = mtask.get(); ODWaveTrackTaskQueue* queue = NULL; if(lockMutex) mQueuesMutex.Lock(); for(unsigned int i=0;i<mQueues.size();i++) { //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].get(); } if(queue) { //Add it to the existing queue but keep the lock since this reference can be deleted. queue->AddTask(std::move(mtask)); if(lockMutex) mQueuesMutex.Unlock(); } else { //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 auto newqueue = make_movable<ODWaveTrackTaskQueue>(); newqueue->AddTask(std::move(mtask)); mQueues.push_back(std::move(newqueue)); if(lockMutex) mQueuesMutex.Unlock(); AddTask(task); } }