1//
2// Activity.h
3//
4// Library: Foundation
5// Package: Threading
6// Module: ActiveObjects
7//
8// Definition of the Activity template class.
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_Activity_INCLUDED
18#define Foundation_Activity_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/RunnableAdapter.h"
23#include "Poco/ThreadPool.h"
24#include "Poco/Event.h"
25#include "Poco/Mutex.h"
26
27
28namespace Poco {
29
30
31template <class C>
32class Activity: public Runnable
33 /// This template class helps to implement active objects.
34 /// An active object uses threads to decouple method
35 /// execution from method invocation, or to perform tasks
36 /// autonomously, without intervention of a caller.
37 ///
38 /// An activity is a (typically longer running) method
39 /// that executes within its own task. Activities can
40 /// be started automatically (upon object construction)
41 /// or manually at a later time. Activities can also
42 /// be stopped at any time. However, to make stopping
43 /// an activity work, the method implementing the
44 /// activity has to check periodically whether it
45 /// has been requested to stop, and if so, return.
46 /// Activities are stopped before the object they belong to is
47 /// destroyed. Methods implementing activities cannot have arguments
48 /// or return values.
49 ///
50 /// Activity objects are used as follows:
51 ///
52 /// class ActiveObject
53 /// {
54 /// public:
55 /// ActiveObject():
56 /// _activity(this, &ActiveObject::runActivity)
57 /// {
58 /// ...
59 /// }
60 ///
61 /// ...
62 ///
63 /// protected:
64 /// void runActivity()
65 /// {
66 /// while (!_activity.isStopped())
67 /// {
68 /// ...
69 /// }
70 /// }
71 ///
72 /// private:
73 /// Activity<ActiveObject> _activity;
74 /// };
75{
76public:
77 typedef RunnableAdapter<C> RunnableAdapterType;
78 typedef typename RunnableAdapterType::Callback Callback;
79
80 Activity(C* pOwner, Callback method):
81 _pOwner(pOwner),
82 _runnable(*pOwner, method),
83 _stopped(true),
84 _running(false),
85 _done(Event::EVENT_MANUALRESET)
86 /// Creates the activity. Call start() to
87 /// start it.
88 {
89 poco_check_ptr (pOwner);
90 }
91
92 ~Activity()
93 /// Stops and destroys the activity.
94 {
95 try
96 {
97 stop();
98 wait();
99 }
100 catch (...)
101 {
102 poco_unexpected();
103 }
104 }
105
106 void start()
107 /// Starts the activity by acquiring a
108 /// thread for it from the default thread pool.
109 {
110 start(ThreadPool::defaultPool());
111 }
112
113 void start(ThreadPool& pool)
114 {
115 FastMutex::ScopedLock lock(_mutex);
116 if (!_running)
117 {
118 _done.reset();
119 _stopped = false;
120 _running = true;
121 try
122 {
123 pool.start(*this);
124 }
125 catch (...)
126 {
127 _running = false;
128 throw;
129 }
130 }
131 }
132
133 void stop()
134 /// Requests to stop the activity.
135 {
136 FastMutex::ScopedLock lock(_mutex);
137 _stopped = true;
138 }
139
140 void wait()
141 /// Waits for the activity to complete.
142 {
143 if (_running)
144 {
145 _done.wait();
146 }
147 }
148
149 void wait(long milliseconds)
150 /// Waits the given interval for the activity to complete.
151 /// An TimeoutException is thrown if the activity does not
152 /// complete within the given interval.
153 {
154 if (_running)
155 {
156 _done.wait(milliseconds);
157 }
158 }
159
160 bool isStopped() const
161 /// Returns true if the activity has been requested to stop.
162 {
163 return _stopped;
164 }
165
166 bool isRunning() const
167 /// Returns true if the activity is running.
168 {
169 return _running;
170 }
171
172protected:
173 void run()
174 {
175 try
176 {
177 _runnable.run();
178 }
179 catch (...)
180 {
181 _running = false;
182 _done.set();
183 throw;
184 }
185 _running = false;
186 _done.set();
187 }
188
189private:
190 Activity();
191 Activity(const Activity&);
192 Activity& operator = (const Activity&);
193
194 C* _pOwner;
195 RunnableAdapterType _runnable;
196 std::atomic<bool> _stopped;
197 std::atomic<bool> _running;
198 Event _done;
199 FastMutex _mutex;
200};
201
202
203} // namespace Poco
204
205
206#endif // Foundation_Activity_INCLUDED
207