Merge pull request #25959 from neo1973/TagLib_deprecation_warnings
[xbmc.git] / lib / libUPnP / Platinum / Source / Core / PltTaskManager.cpp
blob368a05732bf39e822c97caf3ecf33020bda58fcc
1 /*****************************************************************
3 | Platinum - Task Manager
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
6 | All rights reserved.
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 /*----------------------------------------------------------------------
36 | includes
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 */) :
47 m_Queue(NULL),
48 m_MaxTasks(max_items),
49 m_RunningTasks(0),
50 m_Stopping(false)
54 /*----------------------------------------------------------------------
55 | PLT_TaskManager::~PLT_TaskManager
56 +---------------------------------------------------------------------*/
57 PLT_TaskManager::~PLT_TaskManager()
59 Abort();
62 /*----------------------------------------------------------------------
63 | PLT_TaskManager::StartTask
64 +---------------------------------------------------------------------*/
65 NPT_Result
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 +---------------------------------------------------------------------*/
77 NPT_Result
78 PLT_TaskManager::Reset()
80 NPT_AutoLock lock(m_TasksLock);
81 m_Stopping = false;
83 return NPT_SUCCESS;
86 /*----------------------------------------------------------------------
87 | PLT_TaskManager::Abort
88 +---------------------------------------------------------------------*/
89 NPT_Result
90 PLT_TaskManager::Abort()
92 NPT_Cardinal num_running_tasks;
94 do {
96 NPT_AutoLock lock(m_TasksLock);
98 m_Stopping = true;
100 // unblock the queue if any by deleting it
101 if (m_Queue) {
102 int* val = NULL;
103 while(NPT_SUCCEEDED(m_Queue->Pop(val, 0))) delete val;
105 delete m_Queue;
106 m_Queue = NULL;
110 // abort all running tasks
112 NPT_AutoLock lock(m_TasksLock);
114 NPT_List<PLT_ThreadTask*>::Iterator task = m_Tasks.GetFirstItem();
115 while (task) {
116 // stop task if it's not already stopping
117 if (!(*task)->IsAborting(0)) {
118 (*task)->Stop(false);
120 ++task;
123 num_running_tasks = m_Tasks.GetItemCount();
126 if (num_running_tasks == 0)
127 break;
129 NPT_System::Sleep(NPT_TimeInterval(0.05));
130 } while (1);
132 return NPT_SUCCESS;
135 /*----------------------------------------------------------------------
136 | PLT_TaskManager::AddTask
137 +---------------------------------------------------------------------*/
138 NPT_Result
139 PLT_TaskManager::AddTask(PLT_ThreadTask* task)
141 NPT_Result result = NPT_SUCCESS;
142 int *val = NULL;
144 // verify we're not stopping or maxed out number of running tasks
145 do {
146 m_TasksLock.Lock();
148 // returning an error if we're stopping
149 if (m_Stopping) {
150 m_TasksLock.Unlock();
151 delete val;
152 if (task->m_AutoDestroy) delete task;
153 NPT_CHECK_WARNING(NPT_ERROR_INTERRUPTED);
156 if (m_MaxTasks) {
157 val = val?val:new int;
159 if (!m_Queue) {
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) {
176 delete val;
177 if (task->m_AutoDestroy) delete task;
178 NPT_CHECK_WARNING(result);
181 } while (result == NPT_ERROR_TIMEOUT);
183 // start task now
184 if (NPT_FAILED(result = task->StartThread())) {
185 m_TasksLock.Unlock();
187 // Remove task from queue and delete task if autodestroy is set
188 RemoveTask(task);
190 return result;
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();
199 return result;
202 /*----------------------------------------------------------------------
203 | PLT_TaskManager::RemoveTask
204 +---------------------------------------------------------------------*/
205 // called by a PLT_ThreadTask::Run when done
206 NPT_Result
207 PLT_TaskManager::RemoveTask(PLT_ThreadTask* task)
209 NPT_Result result = NPT_SUCCESS;
212 NPT_AutoLock lock(m_TasksLock);
214 if (m_Queue) {
215 int* val = NULL;
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)) {
220 delete val;
221 } else {
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
232 // clean it up
233 if (task->m_AutoDestroy) delete task;
235 return NPT_SUCCESS;