From 498ce9d57957fa46956a18a5c19e7cccb5b5a357 Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nwpope@utu.fi> Date: Sun, 5 Jul 2020 09:45:04 +0300 Subject: [PATCH] Add a transactional class --- components/common/cpp/include/ftl/threads.hpp | 2 + .../common/cpp/include/ftl/transactional.hpp | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 components/common/cpp/include/ftl/transactional.hpp diff --git a/components/common/cpp/include/ftl/threads.hpp b/components/common/cpp/include/ftl/threads.hpp index 6dc002359..03536e2ff 100644 --- a/components/common/cpp/include/ftl/threads.hpp +++ b/components/common/cpp/include/ftl/threads.hpp @@ -31,6 +31,8 @@ #define SHARED_LOCK(M,L) std::shared_lock<std::remove_reference<decltype(M)>::type> L(M); #endif // DEBUG_MUTEX +#define SHARED_LOCK_TYPE(M) std::shared_lock<M> + namespace ftl { extern ctpl::thread_pool pool; } diff --git a/components/common/cpp/include/ftl/transactional.hpp b/components/common/cpp/include/ftl/transactional.hpp new file mode 100644 index 000000000..7c1553ac5 --- /dev/null +++ b/components/common/cpp/include/ftl/transactional.hpp @@ -0,0 +1,42 @@ +#ifndef _FTL_TRANSACTIONAL_HPP_ +#define _FTL_TRANSACTIONAL_HPP_ + +#include <ftl/threads.hpp> + +namespace ftl { + +/** + * Use RAII style transactional objects with shared locking. This wraps an + * object with a lock and provides a release notification mechanism to allow + * completion code. + */ +template <typename T> +class Transactional { + static_assert(std::is_pointer<T>::value, "Transactional type must be a pointer"); + + public: + Transactional(T obj, SHARED_MUTEX &mtx) : ref_(obj), mtx_(mtx), lock_(mtx_) {} + Transactional(T obj, SHARED_MUTEX &mtx, const std::function<void(T)> &complete) : ref_(obj), mtx_(mtx), lock_(mtx_), completed_(complete) {} + Transactional(const Transactional &)=delete; + Transactional()=delete; + ~Transactional() { + lock_.unlock(); + if (completed_) completed_(ref_); + } + + Transactional &operator=(const Transactional &)=delete; + + T operator->() { return ref_; } + + const T operator->() const { return ref_; } + + private: + T ref_; + SHARED_MUTEX &mtx_; + SHARED_LOCK_TYPE(SHARED_MUTEX) lock_; + std::function<void(T)> completed_; +}; + +} + +#endif -- GitLab