Skip to content

Instantly share code, notes, and snippets.

@schulace
Created October 18, 2018 18:25
Show Gist options
  • Select an option

  • Save schulace/deb8f96974f6f646ed37e9486f8f40c8 to your computer and use it in GitHub Desktop.

Select an option

Save schulace/deb8f96974f6f646ed37e9486f8f40c8 to your computer and use it in GitHub Desktop.
A way to wrap a piece of data together with a mutex in c++. Based off of Rust's Mutex<T> implementations.
#include<mutex>
#include<shared_mutex>
#include<memory>
#include<iostream>
using namespace std;
template<class T>
class r_locked_handle {
public:
r_locked_handle(shared_ptr<shared_mutex> m, T* data):data(data), mt(m) {
mt->lock_shared();
}
~r_locked_handle() {
cerr << "read locked handle fell out of scope\n";
mt->unlock_shared();
}
T& operator*() {
return *data;
}
r_locked_handle(r_locked_handle& othr) = delete;
r_locked_handle(r_locked_handle&& othr) = delete;
//: data(move(othr.data)), mt(move(othr.mt)) {};
T* data;
private:
shared_ptr<shared_mutex> mt;
};
template<class T>
class w_locked_handle {
public:
w_locked_handle(shared_ptr<shared_mutex> m, T* data):data(data), mt(m) {
mt->lock();
}
~w_locked_handle() {
cerr << "write locked handle fell out of scope\n";
mt->unlock();
}
T& operator*() {
return *data;
}
w_locked_handle(w_locked_handle& othr) = delete;
w_locked_handle(w_locked_handle&& othr) = delete;
//: data(move(othr.data)), mt(move(othr.mt)) {};
T* data;
private:
shared_ptr<shared_mutex> mt;
};
template<class T>
class rw_locked_structure {
public:
rw_locked_structure(T&& elem):data(move(elem)), m(new shared_mutex){}
unique_ptr<w_locked_handle<T>> acquire_write() {
return unique_ptr<w_locked_handle<T>>(new w_locked_handle<T>(m, &data));
}
unique_ptr<r_locked_handle<T>> acquire_read() {
return unique_ptr<r_locked_handle<T>>(new r_locked_handle<T>(m, &data));
}
T* get_unsafe() {
return &data;
}
private:
T data;
shared_ptr<shared_mutex> m;
};
template<class T>
class locked_handle {
public:
locked_handle(shared_ptr<mutex> m, T* data):data(data), mt(m) {
mt->lock();
}
~locked_handle() {
cerr << "locked handle fell out of scope\n";
mt->unlock();
}
T& operator*() {
return *data;
}
locked_handle(locked_handle&) = delete;
locked_handle(locked_handle&& othr) = delete;
//: data(move(othr.data)), mt(move(othr.mt)) {};
T* data;
private:
shared_ptr<mutex> mt;
};
template<class T>
class locked_structure {
public:
locked_structure(T&& elem):data(move(elem)), m(new mutex){}
unique_ptr<locked_handle<T>> acquire() {
return unique_ptr<locked_handle<T>>(new locked_handle<T>(m, &data));
}
T* get_unsafe() {
return &data;
}
private:
T data;
shared_ptr<mutex> m;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment