1//
2// TaskManager.cpp
3//
4// Library: Foundation
5// Package: Tasks
6// Module: Tasks
7//
8// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/TaskManager.h"
16#include "Poco/TaskNotification.h"
17
18
19namespace Poco {
20
21
22const int TaskManager::MIN_PROGRESS_NOTIFICATION_INTERVAL = 100000; // 100 milliseconds
23
24
25TaskManager::TaskManager(ThreadPool::ThreadAffinityPolicy affinityPolicy):
26 _threadPool(ThreadPool::defaultPool(affinityPolicy))
27{
28}
29
30
31TaskManager::TaskManager(ThreadPool& pool):
32 _threadPool(pool)
33{
34}
35
36
37TaskManager::~TaskManager()
38{
39}
40
41
42void TaskManager::start(Task* pTask, int cpu)
43{
44 TaskPtr pAutoTask(pTask); // take ownership immediately
45 FastMutex::ScopedLock lock(_mutex);
46
47 pAutoTask->setOwner(this);
48 pAutoTask->setState(Task::TASK_STARTING);
49 _taskList.push_back(pAutoTask);
50 try
51 {
52 _threadPool.start(*pAutoTask, pAutoTask->name(), cpu);
53 }
54 catch (...)
55 {
56 // Make sure that we don't act like we own the task since
57 // we never started it. If we leave the task on our task
58 // list, the size of the list is incorrect.
59 _taskList.pop_back();
60 throw;
61 }
62}
63
64
65void TaskManager::startSync(Task* pTask)
66{
67 TaskPtr pAutoTask(pTask); // take ownership immediately
68 ScopedLockWithUnlock<FastMutex> lock(_mutex);
69
70 pAutoTask->setOwner(this);
71 pAutoTask->setState(Task::TASK_STARTING);
72 _taskList.push_back(pAutoTask);
73 lock.unlock();
74 try
75 {
76 pAutoTask->run();
77 }
78 catch (...)
79 {
80 FastMutex::ScopedLock miniLock(_mutex);
81
82 // Make sure that we don't act like we own the task since
83 // we never started it. If we leave the task on our task
84 // list, the size of the list is incorrect.
85 _taskList.pop_back();
86 throw;
87 }
88}
89
90
91void TaskManager::cancelAll()
92{
93 FastMutex::ScopedLock lock(_mutex);
94
95 for (TaskList::iterator it = _taskList.begin(); it != _taskList.end(); ++it)
96 {
97 (*it)->cancel();
98 }
99}
100
101
102void TaskManager::joinAll()
103{
104 _threadPool.joinAll();
105}
106
107
108TaskManager::TaskList TaskManager::taskList() const
109{
110 FastMutex::ScopedLock lock(_mutex);
111
112 return _taskList;
113}
114
115
116void TaskManager::addObserver(const AbstractObserver& observer)
117{
118 _nc.addObserver(observer);
119}
120
121
122void TaskManager::removeObserver(const AbstractObserver& observer)
123{
124 _nc.removeObserver(observer);
125}
126
127
128void TaskManager::postNotification(const Notification::Ptr& pNf)
129{
130 _nc.postNotification(pNf);
131}
132
133
134void TaskManager::taskStarted(Task* pTask)
135{
136 _nc.postNotification(new TaskStartedNotification(pTask));
137}
138
139
140void TaskManager::taskProgress(Task* pTask, float progress)
141{
142 ScopedLockWithUnlock<FastMutex> lock(_mutex);
143
144 if (_lastProgressNotification.isElapsed(MIN_PROGRESS_NOTIFICATION_INTERVAL))
145 {
146 _lastProgressNotification.update();
147 lock.unlock();
148 _nc.postNotification(new TaskProgressNotification(pTask, progress));
149 }
150}
151
152
153void TaskManager::taskCancelled(Task* pTask)
154{
155 _nc.postNotification(new TaskCancelledNotification(pTask));
156}
157
158
159void TaskManager::taskFinished(Task* pTask)
160{
161 TaskPtr currentTask;
162 ScopedLockWithUnlock<FastMutex> lock(_mutex);
163
164 for (TaskList::iterator it = _taskList.begin(); it != _taskList.end(); ++it)
165 {
166 if (*it == pTask)
167 {
168 currentTask = *it;
169 _taskList.erase(it);
170 break;
171 }
172 }
173 lock.unlock();
174
175 _nc.postNotification(new TaskFinishedNotification(pTask));
176}
177
178
179void TaskManager::taskFailed(Task* pTask, const Exception& exc)
180{
181 _nc.postNotification(new TaskFailedNotification(pTask, exc));
182}
183
184
185} // namespace Poco
186