Skip to content

Instantly share code, notes, and snippets.

@akindyakov
Created June 26, 2018 13:28
Show Gist options
  • Save akindyakov/73b27b39c77ddf5060d2f2fed1819f7e to your computer and use it in GitHub Desktop.
Save akindyakov/73b27b39c77ddf5060d2f2fed1819f7e to your computer and use it in GitHub Desktop.
Mutex guarded access controller
#include <iostream>
#include <mutex>
#include <shared_mutex>
#include <string>
#include <thread>
template<
typename Type
, typename MutexType
, typename LockType
>
class AccessController {
public:
explicit AccessController(
Type& value
, MutexType& mutex
)
: value_(value)
, lock_(mutex)
{
}
Type& get() {
return value_;
}
private:
Type& value_;
LockType lock_;
};
template<
typename Type
, typename MutexType = std::mutex
>
class MutexAccessController
{
public:
explicit MutexAccessController(
Type value
)
: value_(std::move(value))
{
}
MutexAccessController(MutexAccessController&&) = default;
MutexAccessController& operator=(MutexAccessController&&) = default;
MutexAccessController(const MutexAccessController&) = delete;
MutexAccessController& operator=(const MutexAccessController&) = delete;
auto shared_controller() const {
return this->controller<std::shared_controller<MutexType>>();
}
auto unique_controller() {
return this->controller<std::unique_controller<MutexType>>();
}
template<
typename LockType
>
auto controller() {
return AccessController<Type, MutexType, LockType>(value_, mutex_);
}
template<
typename LockType
>
auto controller() const {
return AccessController<const Type, MutexType, LockType>(value_, mutex_);
}
MutexType& mutex() const {
return mutex_;
}
Type& unsafe_value() {
return mutex_;
}
const Type& unsafe_value() const {
return mutex_;
}
private:
Type value_;
mutable MutexType mutex_;
};
int main() {
MutexAccessController<std::string, std::shared_timed_mutex> ac{"first"};
{
auto rock = ac.shared_controller();
const auto& str = rock.get();
std::cout << "shared rock: " << str << '\n';
}
{
auto work = ac.unique_controller();
auto& str = work.get();
str += " second";
std::cout << "shared work: " << str << '\n';
}
{
auto work = ac.unique_controller();
std::cout << "shared work: " << work.get() << '\n';
}
MutexAccessController<std::string, std::mutex> acUnique{"second"};
{
auto work = acUnique.unique_controller();
auto& str = work.get();
str += " third";
std::cout << "unique work: " << str << '\n';
}
{
auto work = acUnique.unique_controller();
std::cout << "unique work: " << work.get() << '\n';
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment