Skip to content

Instantly share code, notes, and snippets.

@danielkraic
Created January 16, 2017 20:26
Show Gist options
  • Save danielkraic/0282f8795193d5b8aeac131ca9e2a965 to your computer and use it in GitHub Desktop.
Save danielkraic/0282f8795193d5b8aeac131ca9e2a965 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <memory>
#include <mutex>
// ScopedResource: resource with mutex (acquire resource in constructor, release in destructor)
template <class T>
class ScopedResource {
public:
ScopedResource(std::pair<T*, std::mutex&> resource)
: d_resource(resource.first),
d_mutex(resource.second)
{
d_mutex.lock();
}
ScopedResource(T* resource, std::mutex& mutex)
: d_resource(resource),
d_mutex(mutex)
{
d_mutex.lock();
}
ScopedResource(const ScopedResource&) = delete;
ScopedResource(ScopedResource&&) = delete;
ScopedResource& operator=(const ScopedResource&) = delete;
ScopedResource& operator=(ScopedResource&&) = delete;
~ScopedResource() {
d_mutex.unlock();
}
T* get() {
return d_resource;
}
private:
T* d_resource;
std::mutex& d_mutex;
};
// simple resource container with mutex
template <typename T>
class Resource {
public:
Resource(T* resource)
: d_resource(resource),
d_mutex()
{
}
~Resource() {}
Resource(const Resource&) = delete;
Resource(Resource&&) = delete;
Resource& operator&=(const Resource&) = delete;
Resource& operator&=(Resource&&) = delete;
std::pair<T*, std::mutex&> get() {
return std::make_pair(d_resource, std::ref(d_mutex));
}
private:
T* d_resource;
std::mutex d_mutex;
};
void log(const std::string& msg) {
std::cout << msg << '\n';
}
class A {
public:
A() { log("A()"); }
A(const A& a) { d_val = a.d_val; log("A(const A&)"); }
A(A&& a) { d_val = a.d_val; log("A(A&&)"); }
A& operator&=(const A& a) { d_val = a.d_val; log("A==(const A&)"); return*this; }
A& operator&=(A&& a) { d_val = a.d_val; log("A==(A&&)"); return*this; }
~A() { log("~A()"); }
void say() { log("say"); }
private:
int d_val = 0;
};
int main() {
auto a = std::make_shared<A>();
Resource<A> res(a.get());
log("before lock");
{
ScopedResource<A> sr(res.get());
log("locked area");
sr.get()->say();
}
log("after lock");
std::cout << "Hello\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment