1//
2// Task.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/Task.h"
16#include "Poco/TaskManager.h"
17#include "Poco/Exception.h"
18
19#include <iostream>
20#include <array>
21
22
23namespace Poco {
24
25
26Task::Task(const std::string& rName):
27 _name(rName),
28 _pOwner(0),
29 _progress(0),
30 _state(TASK_IDLE),
31 _cancelEvent(Event::EVENT_MANUALRESET)
32{
33}
34
35
36Task::~Task()
37{
38}
39
40
41void Task::cancel()
42{
43 _state = TASK_CANCELLING;
44 _cancelEvent.set();
45 if (_pOwner)
46 _pOwner->taskCancelled(this);
47}
48
49
50void Task::reset()
51{
52 _progress = 0.0;
53 _state = TASK_IDLE;
54 _cancelEvent.reset();
55}
56
57
58void Task::run()
59{
60 TaskManager* pOwner = getOwner();
61 if (pOwner)
62 pOwner->taskStarted(this);
63 try
64 {
65 /** Task can be already cancelled.
66 * To prevent endless executing already cancelled task _state is assigned to TASK_RUNNING only if _state != TASK_CANCELLING
67 */
68 #pragma clang diagnostic push
69 #pragma clang diagnostic ignored "-Wmissing-braces"
70 std::array<TaskState, 3> allowed_states{TASK_IDLE, TASK_STARTING, TASK_FINISHED};
71 #pragma clang diagnostic pop
72 for (auto & expected : allowed_states)
73 if (_state.compare_exchange_strong(expected, TASK_RUNNING))
74 break;
75
76 if (_state == TASK_RUNNING)
77 runTask();
78 }
79 catch (Exception& exc)
80 {
81 if (pOwner)
82 pOwner->taskFailed(this, exc);
83 }
84 catch (std::exception& exc)
85 {
86 if (pOwner)
87 pOwner->taskFailed(this, SystemException(exc.what()));
88 }
89 catch (...)
90 {
91 if (pOwner)
92 pOwner->taskFailed(this, SystemException("unknown exception"));
93 }
94 _state = TASK_FINISHED;
95 if (pOwner)
96 pOwner->taskFinished(this);
97}
98
99
100bool Task::sleep(long milliseconds)
101{
102 return _cancelEvent.tryWait(milliseconds);
103}
104
105
106void Task::setProgress(float taskProgress)
107{
108 FastMutex::ScopedLock lock(_mutex);
109
110 if (_progress != taskProgress)
111 {
112 _progress = taskProgress;
113 if (_pOwner)
114 _pOwner->taskProgress(this, _progress);
115 }
116}
117
118
119void Task::setOwner(TaskManager* pOwner)
120{
121 FastMutex::ScopedLock lock(_mutex);
122
123 _pOwner = pOwner;
124}
125
126
127void Task::setState(TaskState taskState)
128{
129 _state = taskState;
130}
131
132
133void Task::postNotification(Notification* pNf)
134{
135 poco_check_ptr (pNf);
136
137 FastMutex::ScopedLock lock(_mutex);
138
139 if (_pOwner)
140 {
141 _pOwner->postNotification(pNf);
142 }
143}
144
145
146} // namespace Poco
147