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 #include "Poco/ThreadPool.h"
18 
19 
20 namespace Poco {
21 
22 
23 const int TaskManager::MIN_PROGRESS_NOTIFICATION_INTERVAL = 100000; // 100 milliseconds
24 
25 
TaskManager()26 TaskManager::TaskManager():
27 	_threadPool(ThreadPool::defaultPool())
28 {
29 }
30 
31 
TaskManager(ThreadPool & pool)32 TaskManager::TaskManager(ThreadPool& pool):
33 	_threadPool(pool)
34 {
35 }
36 
37 
~TaskManager()38 TaskManager::~TaskManager()
39 {
40 }
41 
42 
start(Task * pTask)43 void TaskManager::start(Task* pTask)
44 {
45 	TaskPtr pAutoTask(pTask); // take ownership immediately
46 	FastMutex::ScopedLock lock(_mutex);
47 
48 	pAutoTask->setOwner(this);
49 	pAutoTask->setState(Task::TASK_STARTING);
50 	_taskList.push_back(pAutoTask);
51 	try
52 	{
53 		_threadPool.start(*pAutoTask, pAutoTask->name());
54 	}
55 	catch (...)
56 	{
57 		// Make sure that we don't act like we own the task since
58 		// we never started it.  If we leave the task on our task
59 		// list, the size of the list is incorrect.
60 		_taskList.pop_back();
61 		throw;
62 	}
63 }
64 
65 
cancelAll()66 void TaskManager::cancelAll()
67 {
68 	FastMutex::ScopedLock lock(_mutex);
69 
70 	for (auto& pTask: _taskList)
71 	{
72 		pTask->cancel();
73 	}
74 }
75 
76 
joinAll()77 void TaskManager::joinAll()
78 {
79 	_threadPool.joinAll();
80 }
81 
82 
taskList() const83 TaskManager::TaskList TaskManager::taskList() const
84 {
85 	FastMutex::ScopedLock lock(_mutex);
86 
87 	return _taskList;
88 }
89 
90 
addObserver(const AbstractObserver & observer)91 void TaskManager::addObserver(const AbstractObserver& observer)
92 {
93 	_nc.addObserver(observer);
94 }
95 
96 
removeObserver(const AbstractObserver & observer)97 void TaskManager::removeObserver(const AbstractObserver& observer)
98 {
99 	_nc.removeObserver(observer);
100 }
101 
102 
postNotification(const Notification::Ptr & pNf)103 void TaskManager::postNotification(const Notification::Ptr& pNf)
104 {
105 	_nc.postNotification(pNf);
106 }
107 
108 
taskStarted(Task * pTask)109 void TaskManager::taskStarted(Task* pTask)
110 {
111 	_nc.postNotification(new TaskStartedNotification(pTask));
112 }
113 
114 
taskProgress(Task * pTask,float progress)115 void TaskManager::taskProgress(Task* pTask, float progress)
116 {
117 	ScopedLockWithUnlock<FastMutex> lock(_mutex);
118 
119 	if (_lastProgressNotification.isElapsed(MIN_PROGRESS_NOTIFICATION_INTERVAL))
120 	{
121 		_lastProgressNotification.update();
122 		lock.unlock();
123 		_nc.postNotification(new TaskProgressNotification(pTask, progress));
124 	}
125 }
126 
127 
taskCancelled(Task * pTask)128 void TaskManager::taskCancelled(Task* pTask)
129 {
130 	_nc.postNotification(new TaskCancelledNotification(pTask));
131 }
132 
133 
taskFinished(Task * pTask)134 void TaskManager::taskFinished(Task* pTask)
135 {
136 	_nc.postNotification(new TaskFinishedNotification(pTask));
137 
138 	FastMutex::ScopedLock lock(_mutex);
139 	for (TaskList::iterator it = _taskList.begin(); it != _taskList.end(); ++it)
140 	{
141 		if (*it == pTask)
142 		{
143 			_taskList.erase(it);
144 			break;
145 		}
146 	}
147 }
148 
149 
taskFailed(Task * pTask,const Exception & exc)150 void TaskManager::taskFailed(Task* pTask, const Exception& exc)
151 {
152 	_nc.postNotification(new TaskFailedNotification(pTask, exc));
153 }
154 
155 
156 } // namespace Poco
157