1 /*****************************************************************
3 | Platinum - Task Manager
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
7 | http://www.plutinosoft.com
9 | This program is free software; you can redistribute it and/or
10 | modify it under the terms of the GNU General Public License
11 | as published by the Free Software Foundation; either version 2
12 | of the License, or (at your option) any later version.
14 | OEMs, ISVs, VARs and other distributors that combine and
15 | distribute commercially licensed software with Platinum software
16 | and do not wish to distribute the source code for the commercially
17 | licensed software under version 2, or (at your option) any later
18 | version, of the GNU General Public License (the "GPL") must enter
19 | into a commercial license agreement with Plutinosoft, LLC.
20 | licensing@plutinosoft.com
22 | This program is distributed in the hope that it will be useful,
23 | but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | GNU General Public License for more details.
27 | You should have received a copy of the GNU General Public License
28 | along with this program; see the file LICENSE.txt. If not, write to
29 | the Free Software Foundation, Inc.,
30 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 | http://www.gnu.org/licenses/gpl-2.0.html
33 ****************************************************************/
35 /*----------------------------------------------------------------------
37 +---------------------------------------------------------------------*/
38 #include "PltTaskManager.h"
39 #include "PltThreadTask.h"
41 NPT_SET_LOCAL_LOGGER("platinum.core.taskmanager")
43 /*----------------------------------------------------------------------
44 | PLT_TaskManager::PLT_TaskManager
45 +---------------------------------------------------------------------*/
46 PLT_TaskManager::PLT_TaskManager(NPT_Cardinal max_items
/* = 0 */) :
48 m_MaxTasks(max_items
),
54 /*----------------------------------------------------------------------
55 | PLT_TaskManager::~PLT_TaskManager
56 +---------------------------------------------------------------------*/
57 PLT_TaskManager::~PLT_TaskManager()
62 /*----------------------------------------------------------------------
63 | PLT_TaskManager::StartTask
64 +---------------------------------------------------------------------*/
66 PLT_TaskManager::StartTask(PLT_ThreadTask
* task
,
67 NPT_TimeInterval
* delay
/* = NULL*/,
68 bool auto_destroy
/* = true */)
70 NPT_CHECK_POINTER_SEVERE(task
);
71 return task
->Start(this, delay
, auto_destroy
);
74 /*----------------------------------------------------------------------
75 | PLT_TaskManager::Reset
76 +---------------------------------------------------------------------*/
78 PLT_TaskManager::Reset()
80 NPT_AutoLock
lock(m_TasksLock
);
86 /*----------------------------------------------------------------------
87 | PLT_TaskManager::Abort
88 +---------------------------------------------------------------------*/
90 PLT_TaskManager::Abort()
92 NPT_Cardinal num_running_tasks
;
96 NPT_AutoLock
lock(m_TasksLock
);
100 // unblock the queue if any by deleting it
103 while(NPT_SUCCEEDED(m_Queue
->Pop(val
, 0))) delete val
;
110 // abort all running tasks
112 NPT_AutoLock
lock(m_TasksLock
);
114 NPT_List
<PLT_ThreadTask
*>::Iterator task
= m_Tasks
.GetFirstItem();
116 // stop task if it's not already stopping
117 if (!(*task
)->IsAborting(0)) {
118 (*task
)->Stop(false);
123 num_running_tasks
= m_Tasks
.GetItemCount();
126 if (num_running_tasks
== 0)
129 NPT_System::Sleep(NPT_TimeInterval(0.05));
135 /*----------------------------------------------------------------------
136 | PLT_TaskManager::AddTask
137 +---------------------------------------------------------------------*/
139 PLT_TaskManager::AddTask(PLT_ThreadTask
* task
)
141 NPT_Result result
= NPT_SUCCESS
;
144 // verify we're not stopping or maxed out number of running tasks
148 // returning an error if we're stopping
150 m_TasksLock
.Unlock();
152 if (task
->m_AutoDestroy
) delete task
;
153 NPT_CHECK_WARNING(NPT_ERROR_INTERRUPTED
);
157 val
= val
?val
:new int;
160 m_Queue
= new NPT_Queue
<int>(m_MaxTasks
);
164 // try to add to queue but don't block forever if queue is full
165 result
= m_Queue
->Push(val
, 20);
166 if (NPT_SUCCEEDED(result
)) break;
168 // release lock if it's a failure
169 // this gives a chance for the taskmanager
170 // to abort the queue if full
171 m_TasksLock
.Unlock();
173 // if it failed due to something other than a timeout
174 // it probably means the queue is aborting
175 if (result
!= NPT_ERROR_TIMEOUT
) {
177 if (task
->m_AutoDestroy
) delete task
;
178 NPT_CHECK_WARNING(result
);
181 } while (result
== NPT_ERROR_TIMEOUT
);
184 if (NPT_FAILED(result
= task
->StartThread())) {
185 m_TasksLock
.Unlock();
187 // Remove task from queue and delete task if autodestroy is set
193 NPT_LOG_FINER_3("[TaskManager 0x%p] %d/%d running tasks", (void*)this, ++m_RunningTasks
, m_MaxTasks
);
195 // keep track of running task
196 result
= m_Tasks
.Add(task
);
198 m_TasksLock
.Unlock();
202 /*----------------------------------------------------------------------
203 | PLT_TaskManager::RemoveTask
204 +---------------------------------------------------------------------*/
205 // called by a PLT_ThreadTask::Run when done
207 PLT_TaskManager::RemoveTask(PLT_ThreadTask
* task
)
209 NPT_Result result
= NPT_SUCCESS
;
212 NPT_AutoLock
lock(m_TasksLock
);
216 result
= m_Queue
->Pop(val
, 100);
218 // if for some reason the queue is empty, don't block forever
219 if (NPT_SUCCEEDED(result
)) {
222 NPT_LOG_WARNING_1("Failed to pop task from queue %d", result
);
226 NPT_LOG_FINER_3("[TaskManager 0x%p] %d/%d running tasks", (void*)this, --m_RunningTasks
, m_MaxTasks
);
227 m_Tasks
.Remove(task
);
230 // cleanup task only if auto-destroy flag was set
231 // otherwise it's the owner's responsability to
233 if (task
->m_AutoDestroy
) delete task
;