task_manager.cpp
Go to the documentation of this file.00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "stdmisc.h"
00025
00026 #include "nel/misc/task_manager.h"
00027 #include "nel/misc/big_file.h"
00028
00029 using namespace std;
00030
00031 #define NLMISC_DONE_TASK_SIZE 20
00032
00033 namespace NLMISC {
00034
00035
00036
00037
00038 CTaskManager::CTaskManager() : _RunningTask (""), _TaskQueue (""), _DoneTaskQueue ("")
00039 {
00040 _IsTaskRunning = false;
00041 _ThreadRunning = true;
00042 CSynchronized<string>::CAccessor currentTask(&_RunningTask);
00043 currentTask.value () = "";
00044 _Thread = IThread::create(this);
00045 _Thread->start();
00046 _ChangePriorityCallback = NULL;
00047 }
00048
00049
00050
00051
00052 CTaskManager::~CTaskManager()
00053 {
00054 _ThreadRunning = false;
00055 while(!_ThreadRunning)
00056 nlSleep(10);
00057
00058
00059 CSynchronized<std::list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
00060 nlassert(acces.value().empty());
00061 _Thread->wait();
00062 delete _Thread;
00063 _Thread = NULL;
00064
00065 }
00066
00067
00068 void CTaskManager::run(void)
00069 {
00070 IRunnable *runnableTask;
00071 float priorityTask;
00072 while(_ThreadRunning)
00073 {
00074 {
00075 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
00076 if(acces.value().empty())
00077 {
00078 runnableTask = NULL;
00079 }
00080 else
00081 {
00082
00083 changeTaskPriority ();
00084
00085
00086 list<CWaitingTask> &taskList = acces.value();
00087 list<CWaitingTask>::iterator ite = taskList.begin();
00088 list<CWaitingTask>::iterator bestIte = ite;
00089 while (ite != taskList.end())
00090 {
00091 if (ite->Priority < bestIte->Priority)
00092 bestIte = ite;
00093
00094
00095 ite++;
00096 }
00097
00098 _IsTaskRunning = true;
00099 runnableTask = bestIte->Task;
00100 priorityTask = bestIte->Priority;
00101 taskList.erase (bestIte);
00102 }
00103 }
00104 if(runnableTask)
00105 {
00106 {
00107 CSynchronized<string>::CAccessor currentTask(&_RunningTask);
00108 string temp;
00109 runnableTask->getName(temp);
00110 currentTask.value () = temp + " " + toString (priorityTask);
00111 }
00112 runnableTask->run();
00113 {
00114 CSynchronized<string>::CAccessor currentTask(&_RunningTask);
00115 CSynchronized<deque<string> >::CAccessor doneTask(&_DoneTaskQueue);
00116 doneTask.value().push_front (currentTask.value ());
00117 currentTask.value () = "";
00118 if (doneTask.value().size () > NLMISC_DONE_TASK_SIZE)
00119 doneTask.value().resize (NLMISC_DONE_TASK_SIZE);
00120 }
00121
00122 _IsTaskRunning = false;
00123 }
00124 else
00125 {
00126 sleepTask();
00127 }
00128 }
00129 CBigFile::getInstance().currentThreadFinished();
00130 _ThreadRunning = true;
00131 }
00132
00133
00134 void CTaskManager::addTask(IRunnable *r, float priority)
00135 {
00136 CSynchronized<std::list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
00137 acces.value().push_back(CWaitingTask(r, priority));
00138 }
00139
00141 bool CTaskManager::deleteTask(IRunnable *r)
00142 {
00143 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
00144 for(list<CWaitingTask>::iterator it = acces.value().begin(); it != acces.value().end(); it++)
00145 {
00146 if(it->Task == r)
00147 {
00148 acces.value().erase(it);
00149 return true;
00150 }
00151 }
00152 return false;
00153 }
00154
00156 uint CTaskManager::taskListSize(void)
00157 {
00158 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
00159 return acces.value().size();
00160 }
00161
00162
00163 void CTaskManager::waitCurrentTaskToComplete ()
00164 {
00165 while (_IsTaskRunning)
00166 sleepTask();
00167 }
00168
00169
00170
00171 void CTaskManager::dump (std::vector<std::string> &result)
00172 {
00173 CSynchronized<string>::CAccessor accesCurrent(&_RunningTask);
00174 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
00175 CSynchronized<deque<string> >::CAccessor accesDone(&_DoneTaskQueue);
00176
00177 const list<CWaitingTask> &taskList = acces.value();
00178 const deque<string> &taskDone = accesDone.value();
00179 const string &taskCurrent = accesCurrent.value();
00180
00181
00182 result.clear ();
00183 result.reserve (taskList.size () + taskDone.size () + 1);
00184
00185
00186 deque<string>::const_reverse_iterator iteDone = taskDone.rbegin ();
00187 while (iteDone != taskDone.rend ())
00188 {
00189 result.push_back ("Done : " + *iteDone);
00190
00191
00192 iteDone++;
00193 }
00194
00195
00196 if (!taskCurrent.empty())
00197 {
00198 result.push_back ("Current : " + taskCurrent);
00199 }
00200
00201
00202 list<CWaitingTask>::const_iterator ite = taskList.begin ();
00203 while (ite != taskList.end ())
00204 {
00205 string name;
00206 ite->Task->getName (name);
00207 result.push_back ("Waiting : " + name + " " + toString(ite->Priority));
00208
00209
00210 ite++;
00211 }
00212 }
00213
00214
00215 void CTaskManager::clearDump()
00216 {
00217 CSynchronized<deque<string> >::CAccessor accesDone(&_DoneTaskQueue);
00218 accesDone.value().clear();
00219 }
00220
00221
00222
00223 uint CTaskManager::getNumWaitingTasks()
00224 {
00225 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
00226 return acces.value().size();
00227 }
00228
00229
00230
00231 void CTaskManager::changeTaskPriority ()
00232 {
00233 if (_ChangePriorityCallback)
00234 {
00235 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
00236 list<CWaitingTask> &taskList = acces.value();
00237
00238 list<CWaitingTask>::iterator ite = taskList.begin();
00239 while(ite != taskList.end())
00240 {
00241
00242 ite->Priority = _ChangePriorityCallback->getTaskPriority(*(ite->Task));
00243
00244
00245 ite++;
00246 }
00247 }
00248 }
00249
00250
00251
00252 void CTaskManager::registerTaskPriorityCallback (IChangeTaskPriority *callback)
00253 {
00254 _ChangePriorityCallback = callback;
00255 }
00256
00257
00258
00259 }