I am trying to build an abstraction that forces lock acquisition before data can be accessed.
This seems to work, but please tell me if what I am doing horribly wrong, and what I could improve.
I am using C++14 hence shared_timed_mutex
#include <mutex>
#include <shared_mutex>
template <class T>
class rw_locked
{
public:
class write_access
{
public:
write_access(const write_access &) = delete;
write_access &operator=(write_access &) = delete;
write_access &operator=(const write_access &) = delete;
write_access(write_access &&) = delete;
write_access &operator=(write_access &&) = delete;
write_access(rw_locked &t_locked)
: m_lock(t_locked.m_mtx, std::defer_lock), m_hook(&t_locked.m_content){};
T *operator->() { return m_hook; }
T *get() { return m_hook; }
private:
T *m_hook;
const std::shared_lock<std::shared_timed_mutex> m_lock;
};
class read_access
{
public:
read_access(const read_access &) = delete;
read_access &operator=(read_access &) = delete;
read_access &operator=(const read_access &) = delete;
read_access(read_access &&) = delete;
read_access &operator=(read_access &&) = delete;
read_access(rw_locked &t_locked)
: m_lock(t_locked.m_mtx, std::defer_lock), m_hook(&t_locked.m_content){};
const T *operator->() { return m_hook; }
const T *get() { return m_hook; }
private:
const T *m_hook;
const std::unique_lock<std::shared_timed_mutex> m_lock;
};
template <typename... content_args>
explicit rw_locked(content_args &&...t_content_args)
: m_mtx(), m_content(std::forward<content_args>(t_content_args)...)
{
}
private:
std::shared_timed_mutex m_mtx;
T m_content;
};
It's meant to be used like this:
#include <iostream>
#include <string>
#include <vector>
//#include "rw_locked.h"
using locked_strings = rw_locked<std::vector<std::string>>;
int main()
{
locked_strings strs;
// these would be called from threads
{
locked_strings::write_access w_strs(strs);
w_strs->push_back("1");
w_strs->push_back("2");
w_strs->push_back("3");
}
{
locked_strings::read_access r_strs(strs);
for (auto &it : *r_strs.get())
{
std::cout << it << "\n";
}
}
return 0;
}
Thank you very much for your time!