Locking: Add LockerAndInvoker to provide spinQing behaviour
We haven't implemented or tested this yet but it looks promising. Also, it's surprisingly clean!
This commit is contained in:
@@ -0,0 +1,67 @@
|
|||||||
|
#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 LockSpec 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
|
||||||
Reference in New Issue
Block a user