| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // Copyright 2015 Citra Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #pragma once
- #include <algorithm>
- #include <mutex>
- namespace Common {
- template <typename T>
- class SynchronizedWrapper;
- /**
- * Synchronized reference, that keeps a SynchronizedWrapper's mutex locked during its lifetime. This
- * greatly reduces the chance that someone will access the wrapped resource without locking the
- * mutex.
- */
- template <typename T>
- class SynchronizedRef {
- public:
- SynchronizedRef(SynchronizedWrapper<T>& wrapper) : wrapper(&wrapper) {
- wrapper.mutex.lock();
- }
- SynchronizedRef(SynchronizedRef&) = delete;
- SynchronizedRef(SynchronizedRef&& o) : wrapper(o.wrapper) {
- o.wrapper = nullptr;
- }
- ~SynchronizedRef() {
- if (wrapper)
- wrapper->mutex.unlock();
- }
- SynchronizedRef& operator=(SynchronizedRef&) = delete;
- SynchronizedRef& operator=(SynchronizedRef&& o) {
- std::swap(wrapper, o.wrapper);
- return *this;
- }
- T& operator*() {
- return wrapper->data;
- }
- const T& operator*() const {
- return wrapper->data;
- }
- T* operator->() {
- return &wrapper->data;
- }
- const T* operator->() const {
- return &wrapper->data;
- }
- private:
- SynchronizedWrapper<T>* wrapper;
- };
- /**
- * Wraps an object, only allowing access to it via a locking reference wrapper. Good to ensure no
- * one forgets to lock a mutex before acessing an object. To access the wrapped object construct a
- * SyncronizedRef on this wrapper. Inspired by Rust's Mutex type
- * (http://doc.rust-lang.org/std/sync/struct.Mutex.html).
- */
- template <typename T>
- class SynchronizedWrapper {
- public:
- template <typename... Args>
- SynchronizedWrapper(Args&&... args) : data(std::forward<Args>(args)...) {}
- SynchronizedRef<T> Lock() {
- return {*this};
- }
- private:
- template <typename U>
- friend class SynchronizedRef;
- std::mutex mutex;
- T data;
- };
- } // namespace Common
|