mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-10-25 18:22:59 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			211 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //
 | |
| // Activity.h
 | |
| //
 | |
| // $Id: //poco/1.4/Foundation/include/Poco/Activity.h#1 $
 | |
| //
 | |
| // 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.
 | |
| 	{
 | |
| 		FastMutex::ScopedLock lock(_mutex);
 | |
| 
 | |
| 		_stopped = true;
 | |
| 	}
 | |
| 	
 | |
| 	void wait()
 | |
| 		/// Waits for the activity to complete.
 | |
| 	{
 | |
| 		if (_running)
 | |
| 		{
 | |
| 			_done.wait();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	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);
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	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 (...)
 | |
| 		{
 | |
| 			_running = false;
 | |
| 			_done.set();
 | |
| 			throw;
 | |
| 		}
 | |
| 		_running = false;
 | |
| 		_done.set();
 | |
| 	}
 | |
| 	
 | |
| private:
 | |
| 	Activity();
 | |
| 	Activity(const Activity&);
 | |
| 	Activity& operator = (const Activity&);
 | |
| 
 | |
| 	C*                  _pOwner;
 | |
| 	RunnableAdapterType _runnable;
 | |
| 	volatile bool       _stopped;
 | |
| 	volatile bool       _running;
 | |
| 	Event               _done;
 | |
| 	FastMutex           _mutex;
 | |
| };
 | |
| 
 | |
| 
 | |
| } // namespace Poco
 | |
| 
 | |
| 
 | |
| #endif // Foundation_Activity_INCLUDED
 | 
