1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
19 #include "nel/misc/task_manager.h"
20 #include "nel/misc/big_file.h"
24 #define NLMISC_DONE_TASK_SIZE 20
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);
43 _ChangePriorityCallback
= NULL
;
49 CTaskManager::~CTaskManager()
51 _ThreadRunning
= false;
52 while(!_ThreadRunning
)
55 // There should be no remaining Tasks
56 CSynchronized
<std::list
<CWaitingTask
> >::CAccessor
acces(&_TaskQueue
);
57 nlassert(acces
.value().empty());
65 void CTaskManager::run(void)
67 IRunnable
*runnableTask
;
68 float priorityTask
= 0.f
;
72 CSynchronized
<list
<CWaitingTask
> >::CAccessor
acces(&_TaskQueue
);
73 if(acces
.value().empty())
79 // Update task priorities
80 changeTaskPriority ();
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
)
95 _IsTaskRunning
= true;
96 runnableTask
= bestIte
->Task
;
97 priorityTask
= bestIte
->Priority
;
98 taskList
.erase (bestIte
);
104 CSynchronized
<string
>::CAccessor
currentTask(&_RunningTask
);
106 runnableTask
->getName(temp
);
107 currentTask
.value () = temp
+ " " + toString (priorityTask
);
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;
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
++)
145 acces
.value().erase(it
);
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
)
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
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
);
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 ())
203 ite
->Task
->getName (name
);
204 result
.push_back ("Waiting : " + name
+ " " + toString(ite
->Priority
));
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
));
247 // ***************************************************************************
249 void CTaskManager::registerTaskPriorityCallback (IChangeTaskPriority
*callback
)
251 _ChangePriorityCallback
= callback
;
254 // ***************************************************************************