#ifndef LOCKVOKER_H #define LOCKVOKER_H #include #include #include #include #include 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 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& 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& serializedContinuation; InvocationTargetT invocationTarget; }; } // namespace smo #endif // LOCKVOKER_H