mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-11-03 19:40:37 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			207 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//
 | 
						|
// Activity.h
 | 
						|
//
 | 
						|
// Library: Foundation
 | 
						|
// Package: Threading
 | 
						|
// Module:  ActiveObjects
 | 
						|
//
 | 
						|
// Definition of the Activity template class.
 | 
						|
//
 | 
						|
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
 | 
						|
// and Contributors.
 | 
						|
//
 | 
						|
// SPDX-License-Identifier:	BSL-1.0
 | 
						|
//
 | 
						|
 | 
						|
 | 
						|
#ifndef Foundation_Activity_INCLUDED
 | 
						|
#define Foundation_Activity_INCLUDED
 | 
						|
 | 
						|
 | 
						|
#include "Poco/Foundation.h"
 | 
						|
#include "Poco/RunnableAdapter.h"
 | 
						|
#include "Poco/ThreadPool.h"
 | 
						|
#include "Poco/Event.h"
 | 
						|
#include "Poco/Mutex.h"
 | 
						|
 | 
						|
 | 
						|
namespace Poco {
 | 
						|
 | 
						|
 | 
						|
template <class C>
 | 
						|
class Activity: public Runnable
 | 
						|
	/// This template class helps to implement active objects.
 | 
						|
	/// An active object uses threads to decouple method
 | 
						|
	/// execution from method invocation, or to perform tasks
 | 
						|
	/// autonomously, without intervention of a caller.
 | 
						|
	///
 | 
						|
	/// An activity is a (typically longer running) method
 | 
						|
	/// that executes within its own task. Activities can
 | 
						|
	/// be started automatically (upon object construction)
 | 
						|
	/// or manually at a later time. Activities can also
 | 
						|
	/// be stopped at any time. However, to make stopping
 | 
						|
	/// an activity work, the method implementing the
 | 
						|
	/// activity has to check periodically whether it
 | 
						|
	/// has been requested to stop, and if so, return.
 | 
						|
	/// Activities are stopped before the object they belong to is
 | 
						|
	/// destroyed. Methods implementing activities cannot have arguments
 | 
						|
	/// or return values.
 | 
						|
	///
 | 
						|
	/// Activity objects are used as follows:
 | 
						|
	///
 | 
						|
	///     class ActiveObject
 | 
						|
	///     {
 | 
						|
	///     public:
 | 
						|
	///         ActiveObject():
 | 
						|
	///             _activity(this, &ActiveObject::runActivity)
 | 
						|
	///         {
 | 
						|
	///             ...
 | 
						|
	///         }
 | 
						|
	///
 | 
						|
	///         ...
 | 
						|
	///
 | 
						|
	///     protected:
 | 
						|
	///         void runActivity()
 | 
						|
	///         {
 | 
						|
	///             while (!_activity.isStopped())
 | 
						|
	///             {
 | 
						|
	///                 ...
 | 
						|
	///             }
 | 
						|
	///         }
 | 
						|
	///
 | 
						|
	///     private:
 | 
						|
	///         Activity<ActiveObject> _activity;
 | 
						|
	///     };
 | 
						|
{
 | 
						|
public:
 | 
						|
	typedef RunnableAdapter<C> RunnableAdapterType;
 | 
						|
	typedef typename RunnableAdapterType::Callback Callback;
 | 
						|
 | 
						|
	Activity(C* pOwner, Callback method):
 | 
						|
		_pOwner(pOwner),
 | 
						|
		_runnable(*pOwner, method),
 | 
						|
		_stopped(true),
 | 
						|
		_running(false),
 | 
						|
		_done(Event::EVENT_MANUALRESET)
 | 
						|
		/// Creates the activity. Call start() to
 | 
						|
		/// start it.
 | 
						|
	{
 | 
						|
		poco_check_ptr (pOwner);
 | 
						|
	}
 | 
						|
 | 
						|
	~Activity()
 | 
						|
		/// Stops and destroys the activity.
 | 
						|
	{
 | 
						|
		try
 | 
						|
		{
 | 
						|
			stop();
 | 
						|
			wait();
 | 
						|
		}
 | 
						|
		catch (...)
 | 
						|
		{
 | 
						|
			poco_unexpected();
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	void start()
 | 
						|
		/// Starts the activity by acquiring a
 | 
						|
		/// thread for it from the default thread pool.
 | 
						|
	{
 | 
						|
		start(ThreadPool::defaultPool());
 | 
						|
	}
 | 
						|
 | 
						|
	void start(ThreadPool& pool)
 | 
						|
	{
 | 
						|
		FastMutex::ScopedLock lock(_mutex);
 | 
						|
 | 
						|
		if (!_running)
 | 
						|
		{
 | 
						|
			_done.reset();
 | 
						|
			_stopped = false;
 | 
						|
			_running = true;
 | 
						|
			try
 | 
						|
			{
 | 
						|
				pool.start(*this);
 | 
						|
			}
 | 
						|
			catch (...)
 | 
						|
			{
 | 
						|
				_running = false;
 | 
						|
				throw;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	void stop()
 | 
						|
		/// Requests to stop the activity.
 | 
						|
	{
 | 
						|
		_stopped = true;
 | 
						|
	}
 | 
						|
 | 
						|
	void wait()
 | 
						|
		/// Waits for the activity to complete.
 | 
						|
	{
 | 
						|
		if (_running)
 | 
						|
		{
 | 
						|
			_done.wait();
 | 
						|
			_running = false;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	void wait(long milliseconds)
 | 
						|
		/// Waits the given interval for the activity to complete.
 | 
						|
		/// An TimeoutException is thrown if the activity does not
 | 
						|
		/// complete within the given interval.
 | 
						|
	{
 | 
						|
		if (_running)
 | 
						|
		{
 | 
						|
			_done.wait(milliseconds);
 | 
						|
			_running = false;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	bool isStopped() const
 | 
						|
		/// Returns true if the activity has been requested to stop.
 | 
						|
	{
 | 
						|
		return _stopped;
 | 
						|
	}
 | 
						|
 | 
						|
	bool isRunning() const
 | 
						|
		/// Returns true if the activity is running.
 | 
						|
	{
 | 
						|
		return _running;
 | 
						|
	}
 | 
						|
 | 
						|
protected:
 | 
						|
	void run()
 | 
						|
	{
 | 
						|
		try
 | 
						|
		{
 | 
						|
			_runnable.run();
 | 
						|
		}
 | 
						|
		catch (...)
 | 
						|
		{
 | 
						|
			_done.set();
 | 
						|
			throw;
 | 
						|
		}
 | 
						|
		_done.set();
 | 
						|
	}
 | 
						|
 | 
						|
private:
 | 
						|
	Activity();
 | 
						|
	Activity(const Activity&);
 | 
						|
	Activity& operator = (const Activity&);
 | 
						|
 | 
						|
	C*                  _pOwner;
 | 
						|
	RunnableAdapterType _runnable;
 | 
						|
	std::atomic<bool>   _stopped;
 | 
						|
	std::atomic<bool>   _running;
 | 
						|
	Event               _done;
 | 
						|
	FastMutex           _mutex;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
} // namespace Poco
 | 
						|
 | 
						|
 | 
						|
#endif // Foundation_Activity_INCLUDED
 |