Bug 1852740: add tests for the `fetchpriority` attribute in Link headers. r=necko...
[gecko.git] / js / src / threading / Mutex.h
blob4f2ac4940b21fec1f59a5e3e979b87f69d7b32b3
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef threading_Mutex_h
8 #define threading_Mutex_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Maybe.h"
12 #include "mozilla/PlatformMutex.h"
13 #include "mozilla/ThreadLocal.h"
14 #include "mozilla/Vector.h"
16 #include <utility>
18 #include "threading/ThreadId.h"
20 namespace js {
22 // A MutexId secifies the name and mutex order for a mutex.
24 // The mutex order defines the allowed order of mutex acqusition on a single
25 // thread. Mutexes must be acquired in strictly increasing order. Mutexes with
26 // the same order may not be held at the same time by that thread.
27 struct MutexId {
28 const char* name;
29 uint32_t order;
32 // The Mutex class below wraps mozilla::detail::MutexImpl, but we don't want to
33 // use public inheritance, and private inheritance is problematic because
34 // Mutex's friends can access the private parent class as if it was public
35 // inheritance. So use a data member, but for Mutex to access the data member
36 // we must override it and make Mutex a friend.
37 class MutexImpl : public mozilla::detail::MutexImpl {
38 protected:
39 MutexImpl() : mozilla::detail::MutexImpl() {}
41 friend class Mutex;
44 // In debug builds, js::Mutex is a wrapper over MutexImpl that checks correct
45 // locking order is observed.
47 // The class maintains a per-thread stack of currently-held mutexes to enable it
48 // to check this.
49 class Mutex {
50 private:
51 MutexImpl impl_;
53 #ifdef DEBUG
54 const MutexId id_;
55 Mutex* prev_ = nullptr;
56 ThreadId owningThread_;
58 static MOZ_THREAD_LOCAL(Mutex*) HeldMutexStack;
59 #endif
61 public:
62 #ifdef DEBUG
63 static bool Init();
65 explicit Mutex(const MutexId& id) : id_(id) { MOZ_ASSERT(id_.order != 0); }
67 void lock();
68 bool tryLock();
69 void unlock();
70 bool isOwnedByCurrentThread() const;
71 void assertOwnedByCurrentThread() const;
72 #else
73 static bool Init() { return true; }
75 explicit Mutex(const MutexId& id) {}
77 void lock() { impl_.lock(); }
78 bool tryLock() { return impl_.tryLock(); }
79 void unlock() { impl_.unlock(); }
80 void assertOwnedByCurrentThread() const {};
81 #endif
83 private:
84 #ifdef DEBUG
85 void preLockChecks() const;
86 void postLockChecks();
87 void preUnlockChecks();
88 #endif
90 friend class ConditionVariable;
93 } // namespace js
95 #endif // threading_Mutex_h