68 lines
1.6 KiB
C++
68 lines
1.6 KiB
C++
#ifndef LOCKVOKER_H
|
|
#define LOCKVOKER_H
|
|
|
|
#include <functional>
|
|
#include <boost/asio.hpp>
|
|
#include <componentThread.h>
|
|
#include <lockSpec.h>
|
|
#include <asynchronousContinuation.h>
|
|
|
|
namespace smo {
|
|
|
|
/**
|
|
* @brief LockerAndInvoker - Template class for lockvoking mechanism
|
|
*
|
|
* This class wraps a std::bind result and provides locking functionality.
|
|
* When locks cannot be acquired, the object re-posts itself to the io_service
|
|
* queue, implementing the "spinqueueing" pattern.
|
|
*/
|
|
template <class InvocationTargetT>
|
|
class LockerAndInvoker
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor that immediately posts to io_service
|
|
* @param serializedContinuation Reference to the serialized continuation
|
|
* containing LockSet and target io_service
|
|
* @param invocationTarget The std::bind result to invoke when locks are acquired
|
|
*/
|
|
LockerAndInvoker(
|
|
SerializedAsynchronousContinuation<void()>& serializedContinuation,
|
|
InvocationTargetT invocationTarget)
|
|
: serializedContinuation(serializedContinuation),
|
|
invocationTarget(std::move(invocationTarget))
|
|
{
|
|
post();
|
|
}
|
|
|
|
/**
|
|
* @brief Post this object to the io_service
|
|
*/
|
|
void post()
|
|
{ serializedContinuation.caller->getIoService().post(*this); }
|
|
|
|
/**
|
|
* @brief Function call operator - tries to acquire locks and either invokes
|
|
* the target or re-posts itself
|
|
*/
|
|
void operator()()
|
|
{
|
|
if (!serializedContinuation.tryAcquire())
|
|
{
|
|
// Re-post ourselves to try again later
|
|
post();
|
|
return;
|
|
}
|
|
|
|
invocationTarget();
|
|
}
|
|
|
|
private:
|
|
SerializedAsynchronousContinuation<void()>& serializedContinuation;
|
|
InvocationTargetT invocationTarget;
|
|
};
|
|
|
|
} // namespace smo
|
|
|
|
#endif // LOCKVOKER_H
|