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::cancelAll()
66{
67 FastMutex::ScopedLock lock(_mutex);
68
69 for (TaskList::iterator it = _taskList.begin(); it != _taskList.end(); ++it)
70 {
71 (*it)->cancel();
72 }
73}
74
75
76void TaskManager::joinAll()
77{
78 _threadPool.joinAll();
79}
80
81
82TaskManager::TaskList TaskManager::taskList() const
83{
84 FastMutex::ScopedLock lock(_mutex);
85
86 return _taskList;
87}
88
89
90void TaskManager::addObserver(const AbstractObserver& observer)
91{
92 _nc.addObserver(observer);
93}
94
95
96void TaskManager::removeObserver(const AbstractObserver& observer)
97{
98 _nc.removeObserver(observer);
99}
100
101
102void TaskManager::postNotification(const Notification::Ptr& pNf)
103{
104 _nc.postNotification(pNf);
105}
106
107
108void TaskManager::taskStarted(Task* pTask)
109{
110 _nc.postNotification(new TaskStartedNotification(pTask));
111}
112
113
114void TaskManager::taskProgress(Task* pTask, float progress)
115{
116 ScopedLockWithUnlock<FastMutex> lock(_mutex);
117
118 if (_lastProgressNotification.isElapsed(MIN_PROGRESS_NOTIFICATION_INTERVAL))
119 {
120 _lastProgressNotification.update();
121 lock.unlock();
122 _nc.postNotification(new TaskProgressNotification(pTask, progress));
123 }
124}
125
126
127void TaskManager::taskCancelled(Task* pTask)
128{
129 _nc.postNotification(new TaskCancelledNotification(pTask));
130}
131
132
133void TaskManager::taskFinished(Task* pTask)
134{
135 _nc.postNotification(new TaskFinishedNotification(pTask));
136
137 FastMutex::ScopedLock lock(_mutex);
138 for (TaskList::iterator it = _taskList.begin(); it != _taskList.end(); ++it)
139 {
140 if (*it == pTask)
141 {
142 _taskList.erase(it);
143 break;
144 }
145 }
146}
147
148
149void TaskManager::taskFailed(Task* pTask, const Exception& exc)
150{
151 _nc.postNotification(new TaskFailedNotification(pTask, exc));
152}
153
154
155} // namespace Poco
156