/work/obj-fuzz/dist/include/mozilla/DataMutex.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
5 | | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef DataMutex_h__ |
8 | | #define DataMutex_h__ |
9 | | |
10 | | #include "mozilla/Mutex.h" |
11 | | |
12 | | namespace mozilla { |
13 | | |
14 | | // A template to wrap a type with a mutex so that accesses to the type's |
15 | | // data are required to take the lock before accessing it. This ensures |
16 | | // that a mutex is explicitly associated with the data that it protects, |
17 | | // and makes it impossible to access the data without first taking the |
18 | | // associated mutex. |
19 | | // |
20 | | // This is based on Rust's std::sync::Mutex, which operates under the |
21 | | // strategy of locking data, rather than code. |
22 | | // |
23 | | // Examples: |
24 | | // |
25 | | // DataMutex<uint32_t> u32DataMutex(1, "u32DataMutex"); |
26 | | // auto x = u32DataMutex.Lock(); |
27 | | // *x = 4; |
28 | | // assert(*x, 4u); |
29 | | // |
30 | | // DataMutex<nsTArray<uint32_t>> arrayDataMutex("arrayDataMutex"); |
31 | | // auto a = arrayDataMutex.Lock(); |
32 | | // auto& x = a.ref(); |
33 | | // x.AppendElement(1u); |
34 | | // assert(x[0], 1u); |
35 | | // |
36 | | template<typename T> |
37 | | class DataMutex |
38 | | { |
39 | | private: |
40 | | class MOZ_STACK_CLASS AutoLock |
41 | | { |
42 | | public: |
43 | 0 | T* operator->() const { return &ref(); } Unexecuted instantiation: mozilla::DataMutex<mozilla::CDMCaps>::AutoLock::operator->() const Unexecuted instantiation: mozilla::DataMutex<A>::AutoLock::operator->() const |
44 | | |
45 | 0 | T& operator*() const { return ref(); } |
46 | | |
47 | | // Like RefPtr, make this act like its underlying raw pointer type |
48 | | // whenever it is used in a context where a raw pointer is expected. |
49 | | operator T*() const & { return &ref(); } |
50 | | |
51 | | // Like RefPtr, don't allow implicit conversion of temporary to raw pointer. |
52 | | operator T*() const && = delete; |
53 | | |
54 | | T& ref() const |
55 | 0 | { |
56 | 0 | MOZ_ASSERT(mOwner); |
57 | 0 | return mOwner->mValue; |
58 | 0 | } Unexecuted instantiation: mozilla::DataMutex<mozilla::CDMCaps>::AutoLock::ref() const Unexecuted instantiation: mozilla::DataMutex<unsigned int>::AutoLock::ref() const Unexecuted instantiation: mozilla::DataMutex<A>::AutoLock::ref() const Unexecuted instantiation: mozilla::DataMutex<nsTArray<unsigned int> >::AutoLock::ref() const |
59 | | |
60 | | AutoLock(AutoLock&& aOther) |
61 | | : mOwner(aOther.mOwner) |
62 | | { |
63 | | aOther.mOwner = nullptr; |
64 | | } |
65 | | |
66 | | ~AutoLock() |
67 | 0 | { |
68 | 0 | if (mOwner) { |
69 | 0 | mOwner->mMutex.Unlock(); |
70 | 0 | mOwner = nullptr; |
71 | 0 | } |
72 | 0 | } Unexecuted instantiation: mozilla::DataMutex<mozilla::CDMCaps>::AutoLock::~AutoLock() Unexecuted instantiation: mozilla::DataMutex<unsigned int>::AutoLock::~AutoLock() Unexecuted instantiation: mozilla::DataMutex<A>::AutoLock::~AutoLock() Unexecuted instantiation: mozilla::DataMutex<nsTArray<unsigned int> >::AutoLock::~AutoLock() |
73 | | |
74 | | private: |
75 | | friend class DataMutex; |
76 | | |
77 | | AutoLock(const AutoLock& aOther) = delete; |
78 | | |
79 | | explicit AutoLock(DataMutex<T>* aDataMutex) |
80 | | : mOwner(aDataMutex) |
81 | 0 | { |
82 | 0 | MOZ_ASSERT(!!mOwner); |
83 | 0 | mOwner->mMutex.Lock(); |
84 | 0 | } Unexecuted instantiation: mozilla::DataMutex<mozilla::CDMCaps>::AutoLock::AutoLock(mozilla::DataMutex<mozilla::CDMCaps>*) Unexecuted instantiation: mozilla::DataMutex<unsigned int>::AutoLock::AutoLock(mozilla::DataMutex<unsigned int>*) Unexecuted instantiation: mozilla::DataMutex<A>::AutoLock::AutoLock(mozilla::DataMutex<A>*) Unexecuted instantiation: mozilla::DataMutex<nsTArray<unsigned int> >::AutoLock::AutoLock(mozilla::DataMutex<nsTArray<unsigned int> >*) |
85 | | |
86 | | DataMutex<T>* mOwner; |
87 | | }; |
88 | | |
89 | | public: |
90 | | explicit DataMutex(const char* aName) |
91 | | : mMutex(aName) |
92 | 0 | { |
93 | 0 | } Unexecuted instantiation: mozilla::DataMutex<mozilla::CDMCaps>::DataMutex(char const*) Unexecuted instantiation: mozilla::DataMutex<nsTArray<unsigned int> >::DataMutex(char const*) |
94 | | |
95 | | DataMutex(T&& aValue, const char* aName) |
96 | | : mMutex(aName) |
97 | | , mValue(aValue) |
98 | 0 | { |
99 | 0 | } Unexecuted instantiation: mozilla::DataMutex<unsigned int>::DataMutex(unsigned int&&, char const*) Unexecuted instantiation: mozilla::DataMutex<A>::DataMutex(A&&, char const*) |
100 | | |
101 | 0 | AutoLock Lock() { return AutoLock(this); } Unexecuted instantiation: mozilla::DataMutex<mozilla::CDMCaps>::Lock() Unexecuted instantiation: mozilla::DataMutex<unsigned int>::Lock() Unexecuted instantiation: mozilla::DataMutex<A>::Lock() Unexecuted instantiation: mozilla::DataMutex<nsTArray<unsigned int> >::Lock() |
102 | | |
103 | | private: |
104 | | Mutex mMutex; |
105 | | T mValue; |
106 | | }; |
107 | | |
108 | | } // namespace mozilla |
109 | | |
110 | | #endif // DataMutex_h__ |