summaryrefslogtreecommitdiff
path: root/src/common/synchronized_wrapper.h
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-02-05 14:53:25 -0200
committerGravatar Yuri Kunde Schlesner2015-03-01 21:47:13 -0300
commitcd1fbfcf1b70e365d81480ec0f56db19ed02454f (patch)
treeb220b105d1b8016bb258047683bf2d03795c8881 /src/common/synchronized_wrapper.h
parentMerge pull request #616 from archshift/5551 (diff)
downloadyuzu-cd1fbfcf1b70e365d81480ec0f56db19ed02454f.tar.gz
yuzu-cd1fbfcf1b70e365d81480ec0f56db19ed02454f.tar.xz
yuzu-cd1fbfcf1b70e365d81480ec0f56db19ed02454f.zip
Add profiling infrastructure and widget
Diffstat (limited to 'src/common/synchronized_wrapper.h')
-rw-r--r--src/common/synchronized_wrapper.h69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/common/synchronized_wrapper.h b/src/common/synchronized_wrapper.h
new file mode 100644
index 000000000..946252b8c
--- /dev/null
+++ b/src/common/synchronized_wrapper.h
@@ -0,0 +1,69 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <mutex>
8
9namespace Common {
10
11/**
12 * Wraps an object, only allowing access to it via a locking reference wrapper. Good to ensure no
13 * one forgets to lock a mutex before acessing an object. To access the wrapped object construct a
14 * SyncronizedRef on this wrapper. Inspired by Rust's Mutex type (http://doc.rust-lang.org/std/sync/struct.Mutex.html).
15 */
16template <typename T>
17class SynchronizedWrapper {
18public:
19 template <typename... Args>
20 SynchronizedWrapper(Args&&... args) :
21 data(std::forward<Args>(args)...) {
22 }
23
24private:
25 template <typename U>
26 friend class SynchronizedRef;
27
28 std::mutex mutex;
29 T data;
30};
31
32/**
33 * Synchronized reference, that keeps a SynchronizedWrapper's mutex locked during its lifetime. This
34 * greatly reduces the chance that someone will access the wrapped resource without locking the
35 * mutex.
36 */
37template <typename T>
38class SynchronizedRef {
39public:
40 SynchronizedRef(SynchronizedWrapper<T>& wrapper) : wrapper(&wrapper) {
41 wrapper.mutex.lock();
42 }
43
44 SynchronizedRef(SynchronizedRef&) = delete;
45 SynchronizedRef(SynchronizedRef&& o) : wrapper(o.wrapper) {
46 o.wrapper = nullptr;
47 }
48
49 ~SynchronizedRef() {
50 if (wrapper)
51 wrapper->mutex.unlock();
52 }
53
54 SynchronizedRef& operator=(SynchronizedRef&) = delete;
55 SynchronizedRef& operator=(SynchronizedRef&& o) {
56 std::swap(wrapper, o.wrapper);
57 }
58
59 T& operator*() { return wrapper->data; }
60 const T& operator*() const { return wrapper->data; }
61
62 T* operator->() { return &wrapper->data; }
63 const T* operator->() const { return &wrapper->data; }
64
65private:
66 SynchronizedWrapper<T>* wrapper;
67};
68
69} // namespace Common