2023-02-08 11:04:11 +00:00
|
|
|
//
|
|
|
|
// ActiveMethod.h
|
|
|
|
//
|
|
|
|
// Library: Foundation
|
|
|
|
// Package: Threading
|
|
|
|
// Module: ActiveObjects
|
|
|
|
//
|
|
|
|
// Definition of the ActiveMethod class.
|
|
|
|
//
|
|
|
|
// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH.
|
|
|
|
// and Contributors.
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef Foundation_ActiveMethod_INCLUDED
|
|
|
|
#define Foundation_ActiveMethod_INCLUDED
|
|
|
|
|
|
|
|
|
|
|
|
#include "Poco/ActiveResult.h"
|
|
|
|
#include "Poco/ActiveRunnable.h"
|
|
|
|
#include "Poco/ActiveStarter.h"
|
|
|
|
#include "Poco/AutoPtr.h"
|
2023-02-13 09:22:33 +00:00
|
|
|
#include "Poco/Foundation.h"
|
2023-02-08 11:04:11 +00:00
|
|
|
|
|
|
|
|
2023-02-13 09:22:33 +00:00
|
|
|
namespace Poco
|
|
|
|
{
|
2023-02-08 11:04:11 +00:00
|
|
|
|
|
|
|
|
2023-02-13 09:22:33 +00:00
|
|
|
template <class ResultType, class ArgType, class OwnerType, class StarterType = ActiveStarter<OwnerType>>
|
2023-02-08 11:04:11 +00:00
|
|
|
class ActiveMethod
|
2023-02-13 09:22:33 +00:00
|
|
|
/// An active method is a method that, when called, executes
|
|
|
|
/// in its own thread. ActiveMethod's take exactly one
|
|
|
|
/// argument and can return a value. To pass more than one
|
|
|
|
/// argument to the method, use a struct.
|
|
|
|
/// The following example shows how to add an ActiveMethod
|
|
|
|
/// to a class:
|
|
|
|
///
|
|
|
|
/// class ActiveObject
|
|
|
|
/// {
|
|
|
|
/// public:
|
|
|
|
/// ActiveObject():
|
|
|
|
/// exampleActiveMethod(this, &ActiveObject::exampleActiveMethodImpl)
|
|
|
|
/// {
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// ActiveMethod<std::string, std::string, ActiveObject> exampleActiveMethod;
|
|
|
|
///
|
|
|
|
/// protected:
|
|
|
|
/// std::string exampleActiveMethodImpl(const std::string& arg)
|
|
|
|
/// {
|
|
|
|
/// ...
|
|
|
|
/// }
|
|
|
|
/// };
|
|
|
|
///
|
|
|
|
/// And following is an example that shows how to invoke an ActiveMethod.
|
|
|
|
///
|
|
|
|
/// ActiveObject myActiveObject;
|
|
|
|
/// ActiveResult<std::string> result = myActiveObject.exampleActiveMethod("foo");
|
|
|
|
/// ...
|
|
|
|
/// result.wait();
|
|
|
|
/// std::cout << result.data() << std::endl;
|
|
|
|
///
|
|
|
|
/// The way an ActiveMethod is started can be changed by passing a StarterType
|
|
|
|
/// template argument with a corresponding class. The default ActiveStarter
|
|
|
|
/// starts the method in its own thread, obtained from a thread pool.
|
|
|
|
///
|
|
|
|
/// For an alternative implementation of StarterType, see ActiveDispatcher.
|
|
|
|
///
|
|
|
|
/// For methods that do not require an argument or a return value, the Void
|
|
|
|
/// class can be used.
|
2023-02-08 11:04:11 +00:00
|
|
|
{
|
|
|
|
public:
|
2023-02-13 09:22:33 +00:00
|
|
|
typedef ResultType (OwnerType::*Callback)(const ArgType &);
|
|
|
|
typedef ActiveResult<ResultType> ActiveResultType;
|
|
|
|
typedef ActiveRunnable<ResultType, ArgType, OwnerType> ActiveRunnableType;
|
|
|
|
|
|
|
|
ActiveMethod(OwnerType * pOwner, Callback method) : _pOwner(pOwner), _method(method)
|
|
|
|
/// Creates an ActiveMethod object.
|
|
|
|
{
|
|
|
|
poco_check_ptr(pOwner);
|
|
|
|
}
|
|
|
|
|
|
|
|
ActiveResultType operator()(const ArgType & arg)
|
|
|
|
/// Invokes the ActiveMethod.
|
|
|
|
{
|
|
|
|
ActiveResultType result(new ActiveResultHolder<ResultType>());
|
|
|
|
ActiveRunnableBase::Ptr pRunnable(new ActiveRunnableType(_pOwner, _method, arg, result));
|
|
|
|
StarterType::start(_pOwner, pRunnable);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ActiveMethod(const ActiveMethod & other) : _pOwner(other._pOwner), _method(other._method) { }
|
|
|
|
|
|
|
|
ActiveMethod & operator=(const ActiveMethod & other)
|
|
|
|
{
|
|
|
|
ActiveMethod tmp(other);
|
|
|
|
swap(tmp);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(ActiveMethod & other)
|
|
|
|
{
|
|
|
|
std::swap(_pOwner, other._pOwner);
|
|
|
|
std::swap(_method, other._method);
|
|
|
|
}
|
2023-02-08 11:04:11 +00:00
|
|
|
|
|
|
|
private:
|
2023-02-13 09:22:33 +00:00
|
|
|
ActiveMethod();
|
2023-02-08 11:04:11 +00:00
|
|
|
|
2023-02-13 09:22:33 +00:00
|
|
|
OwnerType * _pOwner;
|
|
|
|
Callback _method;
|
2023-02-08 11:04:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <class ResultType, class OwnerType, class StarterType>
|
2023-02-13 09:22:33 +00:00
|
|
|
class ActiveMethod<ResultType, void, OwnerType, StarterType>
|
|
|
|
/// An active method is a method that, when called, executes
|
|
|
|
/// in its own thread. ActiveMethod's take exactly one
|
|
|
|
/// argument and can return a value. To pass more than one
|
|
|
|
/// argument to the method, use a struct.
|
|
|
|
/// The following example shows how to add an ActiveMethod
|
|
|
|
/// to a class:
|
|
|
|
///
|
|
|
|
/// class ActiveObject
|
|
|
|
/// {
|
|
|
|
/// public:
|
|
|
|
/// ActiveObject():
|
|
|
|
/// exampleActiveMethod(this, &ActiveObject::exampleActiveMethodImpl)
|
|
|
|
/// {
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// ActiveMethod<std::string, std::string, ActiveObject> exampleActiveMethod;
|
|
|
|
///
|
|
|
|
/// protected:
|
|
|
|
/// std::string exampleActiveMethodImpl(const std::string& arg)
|
|
|
|
/// {
|
|
|
|
/// ...
|
|
|
|
/// }
|
|
|
|
/// };
|
|
|
|
///
|
|
|
|
/// And following is an example that shows how to invoke an ActiveMethod.
|
|
|
|
///
|
|
|
|
/// ActiveObject myActiveObject;
|
|
|
|
/// ActiveResult<std::string> result = myActiveObject.exampleActiveMethod("foo");
|
|
|
|
/// ...
|
|
|
|
/// result.wait();
|
|
|
|
/// std::cout << result.data() << std::endl;
|
|
|
|
///
|
|
|
|
/// The way an ActiveMethod is started can be changed by passing a StarterType
|
|
|
|
/// template argument with a corresponding class. The default ActiveStarter
|
|
|
|
/// starts the method in its own thread, obtained from a thread pool.
|
|
|
|
///
|
|
|
|
/// For an alternative implementation of StarterType, see ActiveDispatcher.
|
|
|
|
///
|
|
|
|
/// For methods that do not require an argument or a return value, simply use void.
|
2023-02-08 11:04:11 +00:00
|
|
|
{
|
|
|
|
public:
|
2023-02-13 09:22:33 +00:00
|
|
|
typedef ResultType (OwnerType::*Callback)(void);
|
|
|
|
typedef ActiveResult<ResultType> ActiveResultType;
|
|
|
|
typedef ActiveRunnable<ResultType, void, OwnerType> ActiveRunnableType;
|
|
|
|
|
|
|
|
ActiveMethod(OwnerType * pOwner, Callback method) : _pOwner(pOwner), _method(method)
|
|
|
|
/// Creates an ActiveMethod object.
|
|
|
|
{
|
|
|
|
poco_check_ptr(pOwner);
|
|
|
|
}
|
|
|
|
|
|
|
|
ActiveResultType operator()(void)
|
|
|
|
/// Invokes the ActiveMethod.
|
|
|
|
{
|
|
|
|
ActiveResultType result(new ActiveResultHolder<ResultType>());
|
|
|
|
ActiveRunnableBase::Ptr pRunnable(new ActiveRunnableType(_pOwner, _method, result));
|
|
|
|
StarterType::start(_pOwner, pRunnable);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ActiveMethod(const ActiveMethod & other) : _pOwner(other._pOwner), _method(other._method) { }
|
|
|
|
|
|
|
|
ActiveMethod & operator=(const ActiveMethod & other)
|
|
|
|
{
|
|
|
|
ActiveMethod tmp(other);
|
|
|
|
swap(tmp);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void swap(ActiveMethod & other)
|
|
|
|
{
|
|
|
|
std::swap(_pOwner, other._pOwner);
|
|
|
|
std::swap(_method, other._method);
|
|
|
|
}
|
2023-02-08 11:04:11 +00:00
|
|
|
|
|
|
|
private:
|
2023-02-13 09:22:33 +00:00
|
|
|
ActiveMethod();
|
2023-02-08 11:04:11 +00:00
|
|
|
|
2023-02-13 09:22:33 +00:00
|
|
|
OwnerType * _pOwner;
|
|
|
|
Callback _method;
|
2023-02-08 11:04:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace Poco
|
|
|
|
|
|
|
|
|
|
|
|
#endif // Foundation_ActiveMethod_INCLUDED
|