Created
October 18, 2018 18:25
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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