Merge branch 'ryzom/ark-features' into main/gingo-test
[ryzomcore.git] / nel / src / misc / task_manager.cpp
blobc4ec292886dea2aa9a5f1024869518a8db9f9414
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "stdmisc.h"
19 #include "nel/misc/task_manager.h"
20 #include "nel/misc/big_file.h"
22 using namespace std;
24 #define NLMISC_DONE_TASK_SIZE 20
26 #ifdef DEBUG_NEW
27 #define new DEBUG_NEW
28 #endif
30 namespace NLMISC {
33 * Constructor
35 CTaskManager::CTaskManager() : _RunningTask (""), _TaskQueue (""), _DoneTaskQueue ("")
37 _IsTaskRunning = false;
38 _ThreadRunning = true;
39 CSynchronized<string>::CAccessor currentTask(&_RunningTask);
40 currentTask.value ().clear();
41 _Thread = IThread::create(this);
42 _Thread->start();
43 _ChangePriorityCallback = NULL;
47 * Destructeur
49 CTaskManager::~CTaskManager()
51 _ThreadRunning = false;
52 while(!_ThreadRunning)
53 nlSleep(10);
55 // There should be no remaining Tasks
56 CSynchronized<std::list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
57 nlassert(acces.value().empty());
58 _Thread->wait();
59 delete _Thread;
60 _Thread = NULL;
64 // Manage TaskQueue
65 void CTaskManager::run(void)
67 IRunnable *runnableTask;
68 float priorityTask = 0.f;
69 while(_ThreadRunning)
72 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
73 if(acces.value().empty())
75 runnableTask = NULL;
77 else
79 // Update task priorities
80 changeTaskPriority ();
82 // Get the best task
83 list<CWaitingTask> &taskList = acces.value();
84 list<CWaitingTask>::iterator ite = taskList.begin();
85 list<CWaitingTask>::iterator bestIte = ite;
86 while (ite != taskList.end())
88 if (ite->Priority < bestIte->Priority)
89 bestIte = ite;
91 // Next task;
92 ite++;
95 _IsTaskRunning = true;
96 runnableTask = bestIte->Task;
97 priorityTask = bestIte->Priority;
98 taskList.erase (bestIte);
101 if(runnableTask)
104 CSynchronized<string>::CAccessor currentTask(&_RunningTask);
105 string temp;
106 runnableTask->getName(temp);
107 currentTask.value () = temp + " " + toString (priorityTask);
109 runnableTask->run();
111 CSynchronized<string>::CAccessor currentTask(&_RunningTask);
112 CSynchronized<deque<string> >::CAccessor doneTask(&_DoneTaskQueue);
113 doneTask.value().push_front (currentTask.value ());
114 currentTask.value ().clear();
115 if (doneTask.value().size () > NLMISC_DONE_TASK_SIZE)
116 doneTask.value().resize (NLMISC_DONE_TASK_SIZE);
119 _IsTaskRunning = false;
121 else
123 sleepTask();
126 CBigFile::getInstance().currentThreadFinished();
127 _ThreadRunning = true;
130 // Add a task to TaskManager
131 void CTaskManager::addTask(IRunnable *r, float priority)
133 CSynchronized<std::list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
134 acces.value().push_back(CWaitingTask(r, priority));
137 /// Delete a task, only if task is not running, return true if found and deleted
138 bool CTaskManager::deleteTask(IRunnable *r)
140 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
141 for(list<CWaitingTask>::iterator it = acces.value().begin(); it != acces.value().end(); it++)
143 if(it->Task == r)
145 acces.value().erase(it);
146 return true;
149 return false;
152 /// Task list size
153 uint CTaskManager::taskListSize(void)
155 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
156 return (uint)acces.value().size();
160 void CTaskManager::waitCurrentTaskToComplete ()
162 while (_IsTaskRunning)
163 sleepTask();
166 // ***************************************************************************
168 void CTaskManager::dump (std::vector<std::string> &result)
170 CSynchronized<string>::CAccessor accesCurrent(&_RunningTask);
171 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
172 CSynchronized<deque<string> >::CAccessor accesDone(&_DoneTaskQueue);
174 const list<CWaitingTask> &taskList = acces.value();
175 const deque<string> &taskDone = accesDone.value();
176 const string &taskCurrent = accesCurrent.value();
178 // Resize the destination array
179 result.clear ();
180 result.reserve (taskList.size () + taskDone.size () + 1);
182 // Add the done strings
183 deque<string>::const_reverse_iterator iteDone = taskDone.rbegin ();
184 while (iteDone != taskDone.rend ())
186 result.push_back ("Done : " + *iteDone);
188 // Next task
189 iteDone++;
192 // Add the current string
193 if (!taskCurrent.empty())
195 result.push_back ("Current : " + taskCurrent);
198 // Add the waiting strings
199 list<CWaitingTask>::const_iterator ite = taskList.begin ();
200 while (ite != taskList.end ())
202 string name;
203 ite->Task->getName (name);
204 result.push_back ("Waiting : " + name + " " + toString(ite->Priority));
206 // Next task
207 ite++;
211 // ***************************************************************************
212 void CTaskManager::clearDump()
214 CSynchronized<deque<string> >::CAccessor accesDone(&_DoneTaskQueue);
215 accesDone.value().clear();
218 // ***************************************************************************
220 uint CTaskManager::getNumWaitingTasks()
222 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
223 return (uint)acces.value().size();
226 // ***************************************************************************
228 void CTaskManager::changeTaskPriority ()
230 if (_ChangePriorityCallback)
232 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
233 list<CWaitingTask> &taskList = acces.value();
235 list<CWaitingTask>::iterator ite = taskList.begin();
236 while(ite != taskList.end())
238 // Get the new priority
239 ite->Priority = _ChangePriorityCallback->getTaskPriority(*(ite->Task));
241 // Next task
242 ite++;
247 // ***************************************************************************
249 void CTaskManager::registerTaskPriorityCallback (IChangeTaskPriority *callback)
251 _ChangePriorityCallback = callback;
254 // ***************************************************************************
256 } // NLMISC