Bug 1732219 - Add API for fetching the preview image. r=geckoview-reviewers,agi,mconley
[gecko.git] / dom / workers / Queue.h
blob7b4d80143238c9dc7cb7f223e12499d75211348d
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 mozilla_dom_workerinternal_Queue_h
8 #define mozilla_dom_workerinternal_Queue_h
10 #include "mozilla/Mutex.h"
11 #include "nsTArray.h"
13 namespace mozilla {
14 namespace dom {
15 namespace workerinternals {
17 template <typename T, int TCount>
18 struct StorageWithTArray {
19 typedef AutoTArray<T, TCount> StorageType;
21 static void Reverse(StorageType& aStorage) {
22 uint32_t length = aStorage.Length();
23 for (uint32_t index = 0; index < length / 2; index++) {
24 uint32_t reverseIndex = length - 1 - index;
26 T t1 = aStorage.ElementAt(index);
27 T t2 = aStorage.ElementAt(reverseIndex);
29 aStorage.ReplaceElementsAt(index, 1, t2);
30 aStorage.ReplaceElementsAt(reverseIndex, 1, t1);
34 static bool IsEmpty(const StorageType& aStorage) {
35 return !!aStorage.IsEmpty();
38 static void Push(StorageType& aStorage, const T& aEntry) {
39 aStorage.AppendElement(aEntry);
42 static bool Pop(StorageType& aStorage, T& aEntry) {
43 if (IsEmpty(aStorage)) {
44 return false;
47 aEntry = aStorage.PopLastElement();
48 return true;
51 static void Clear(StorageType& aStorage) { aStorage.Clear(); }
53 static void Compact(StorageType& aStorage) { aStorage.Compact(); }
56 class LockingWithMutex {
57 mozilla::Mutex mMutex;
59 protected:
60 LockingWithMutex() : mMutex("LockingWithMutex::mMutex") {}
62 void Lock() { mMutex.Lock(); }
64 void Unlock() { mMutex.Unlock(); }
66 class AutoLock {
67 LockingWithMutex& mHost;
69 public:
70 explicit AutoLock(LockingWithMutex& aHost) : mHost(aHost) { mHost.Lock(); }
72 ~AutoLock() { mHost.Unlock(); }
75 friend class AutoLock;
78 class NoLocking {
79 protected:
80 void Lock() {}
82 void Unlock() {}
84 class AutoLock {
85 public:
86 explicit AutoLock(NoLocking& aHost) {}
88 ~AutoLock() = default;
92 template <typename T, int TCount = 256, class LockingPolicy = NoLocking,
93 class StoragePolicy =
94 StorageWithTArray<T, TCount % 2 ? TCount / 2 + 1 : TCount / 2> >
95 class Queue : public LockingPolicy {
96 typedef typename StoragePolicy::StorageType StorageType;
97 typedef typename LockingPolicy::AutoLock AutoLock;
99 StorageType mStorage1;
100 StorageType mStorage2;
102 StorageType* mFront;
103 StorageType* mBack;
105 public:
106 Queue() : mFront(&mStorage1), mBack(&mStorage2) {}
108 bool IsEmpty() {
109 AutoLock lock(*this);
110 return StoragePolicy::IsEmpty(*mFront) && StoragePolicy::IsEmpty(*mBack);
113 void Push(const T& aEntry) {
114 AutoLock lock(*this);
115 StoragePolicy::Push(*mBack, aEntry);
118 bool Pop(T& aEntry) {
119 AutoLock lock(*this);
120 if (StoragePolicy::IsEmpty(*mFront)) {
121 StoragePolicy::Compact(*mFront);
122 StoragePolicy::Reverse(*mBack);
123 StorageType* tmp = mFront;
124 mFront = mBack;
125 mBack = tmp;
127 return StoragePolicy::Pop(*mFront, aEntry);
130 void Clear() {
131 AutoLock lock(*this);
132 StoragePolicy::Clear(*mFront);
133 StoragePolicy::Clear(*mBack);
136 // XXX Do we need this?
137 void Lock() { LockingPolicy::Lock(); }
139 // XXX Do we need this?
140 void Unlock() { LockingPolicy::Unlock(); }
142 private:
143 // Queue is not copyable.
144 Queue(const Queue&);
145 Queue& operator=(const Queue&);
148 } // namespace workerinternals
149 } // namespace dom
150 } // namespace mozilla
152 #endif /* mozilla_dom_workerinternals_Queue_h*/