Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/StateMirroring.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
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#if !defined(StateMirroring_h_)
8
#define StateMirroring_h_
9
10
#include "mozilla/Maybe.h"
11
#include "mozilla/MozPromise.h"
12
#include "mozilla/StateWatching.h"
13
#include "mozilla/TaskDispatcher.h"
14
#include "mozilla/UniquePtr.h"
15
#include "mozilla/Unused.h"
16
17
#include "mozilla/Logging.h"
18
#include "nsISupportsImpl.h"
19
20
/*
21
 * The state-mirroring machinery allows pieces of interesting state to be
22
 * observed on multiple thread without locking. The basic strategy is to track
23
 * changes in a canonical value and post updates to other threads that hold
24
 * mirrors for that value.
25
 *
26
 * One problem with the naive implementation of such a system is that some pieces
27
 * of state need to be updated atomically, and certain other operations need to
28
 * wait for these atomic updates to complete before executing. The state-mirroring
29
 * machinery solves this problem by requiring that its owner thread uses tail
30
 * dispatch, and posting state update events (which should always be run first by
31
 * TaskDispatcher implementations) to that tail dispatcher. This ensures that
32
 * state changes are always atomic from the perspective of observing threads.
33
 *
34
 * Given that state-mirroring is an automatic background process, we try to avoid
35
 * burdening the caller with worrying too much about teardown. To that end, we
36
 * don't assert dispatch success for any of the notifications, and assume that
37
 * any canonical or mirror owned by a thread for whom dispatch fails will soon
38
 * be disconnected by its holder anyway.
39
 *
40
 * Given that semantics may change and comments tend to go out of date, we
41
 * deliberately don't provide usage examples here. Grep around to find them.
42
 */
43
44
namespace mozilla {
45
46
// Mirror<T> and Canonical<T> inherit WatchTarget, so we piggy-back on the
47
// logging that WatchTarget already does. Given that, it makes sense to share
48
// the same log module.
49
#define MIRROR_LOG(x, ...) \
50
0
  MOZ_ASSERT(gStateWatchingLog); \
51
0
  MOZ_LOG(gStateWatchingLog, LogLevel::Debug, (x, ##__VA_ARGS__))
52
53
template<typename T> class AbstractMirror;
54
55
/*
56
 * AbstractCanonical is a superclass from which all Canonical values must
57
 * inherit. It serves as the interface of operations which may be performed (via
58
 * asynchronous dispatch) by other threads, in particular by the corresponding
59
 * Mirror value.
60
 */
61
template<typename T>
62
class AbstractCanonical
63
{
64
public:
65
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractCanonical)
66
0
  AbstractCanonical(AbstractThread* aThread) : mOwnerThread(aThread) {}
Unexecuted instantiation: mozilla::AbstractCanonical<double>::AbstractCanonical(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractCanonical<bool>::AbstractCanonical(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::MediaDecoder::PlayState>::AbstractCanonical(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractCanonical<nsMainThreadPtrHandle<nsIPrincipal> >::AbstractCanonical(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::Maybe<mozilla::media::TimeUnit> >::AbstractCanonical(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::media::TimeUnit>::AbstractCanonical(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::media::TimeIntervals>::AbstractCanonical(mozilla::AbstractThread*)
67
  virtual void AddMirror(AbstractMirror<T>* aMirror) = 0;
68
  virtual void RemoveMirror(AbstractMirror<T>* aMirror) = 0;
69
70
0
  AbstractThread* OwnerThread() const { return mOwnerThread; }
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::Maybe<mozilla::media::TimeUnit> >::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::media::TimeIntervals>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::media::TimeUnit>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractCanonical<bool>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::MediaDecoder::PlayState>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractCanonical<double>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractCanonical<nsMainThreadPtrHandle<nsIPrincipal> >::OwnerThread() const
71
protected:
72
0
  virtual ~AbstractCanonical() {}
Unexecuted instantiation: mozilla::AbstractCanonical<double>::~AbstractCanonical()
Unexecuted instantiation: mozilla::AbstractCanonical<bool>::~AbstractCanonical()
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::MediaDecoder::PlayState>::~AbstractCanonical()
Unexecuted instantiation: mozilla::AbstractCanonical<nsMainThreadPtrHandle<nsIPrincipal> >::~AbstractCanonical()
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::Maybe<mozilla::media::TimeUnit> >::~AbstractCanonical()
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::media::TimeUnit>::~AbstractCanonical()
Unexecuted instantiation: mozilla::AbstractCanonical<mozilla::media::TimeIntervals>::~AbstractCanonical()
73
  RefPtr<AbstractThread> mOwnerThread;
74
};
75
76
/*
77
 * AbstractMirror is a superclass from which all Mirror values must
78
 * inherit. It serves as the interface of operations which may be performed (via
79
 * asynchronous dispatch) by other threads, in particular by the corresponding
80
 * Canonical value.
81
 */
82
template<typename T>
83
class AbstractMirror
84
{
85
public:
86
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractMirror)
87
0
  AbstractMirror(AbstractThread* aThread) : mOwnerThread(aThread) {}
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::media::TimeIntervals>::AbstractMirror(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::media::TimeUnit>::AbstractMirror(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::Maybe<mozilla::media::TimeUnit> >::AbstractMirror(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractMirror<bool>::AbstractMirror(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::MediaDecoder::PlayState>::AbstractMirror(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractMirror<double>::AbstractMirror(mozilla::AbstractThread*)
Unexecuted instantiation: mozilla::AbstractMirror<nsMainThreadPtrHandle<nsIPrincipal> >::AbstractMirror(mozilla::AbstractThread*)
88
  virtual void UpdateValue(const T& aNewValue) = 0;
89
  virtual void NotifyDisconnected() = 0;
90
91
0
  AbstractThread* OwnerThread() const { return mOwnerThread; }
Unexecuted instantiation: mozilla::AbstractMirror<double>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractMirror<bool>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::MediaDecoder::PlayState>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractMirror<nsMainThreadPtrHandle<nsIPrincipal> >::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::Maybe<mozilla::media::TimeUnit> >::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::media::TimeUnit>::OwnerThread() const
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::media::TimeIntervals>::OwnerThread() const
92
protected:
93
0
  virtual ~AbstractMirror() {}
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::media::TimeIntervals>::~AbstractMirror()
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::media::TimeUnit>::~AbstractMirror()
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::Maybe<mozilla::media::TimeUnit> >::~AbstractMirror()
Unexecuted instantiation: mozilla::AbstractMirror<bool>::~AbstractMirror()
Unexecuted instantiation: mozilla::AbstractMirror<mozilla::MediaDecoder::PlayState>::~AbstractMirror()
Unexecuted instantiation: mozilla::AbstractMirror<double>::~AbstractMirror()
Unexecuted instantiation: mozilla::AbstractMirror<nsMainThreadPtrHandle<nsIPrincipal> >::~AbstractMirror()
94
  RefPtr<AbstractThread> mOwnerThread;
95
};
96
97
/*
98
 * Canonical<T> is a wrapper class that allows a given value to be mirrored by other
99
 * threads. It maintains a list of active mirrors, and queues updates for them
100
 * when the internal value changes. When changing the value, the caller needs to
101
 * pass a TaskDispatcher object, which fires the updates at the appropriate time.
102
 * Canonical<T> is also a WatchTarget, and may be set up to trigger other routines
103
 * (on the same thread) when the canonical value changes.
104
 *
105
 * Canonical<T> is intended to be used as a member variable, so it doesn't actually
106
 * inherit AbstractCanonical<T> (a refcounted type). Rather, it contains an inner
107
 * class called |Impl| that implements most of the interesting logic.
108
 */
109
template<typename T>
110
class Canonical
111
{
112
public:
113
  Canonical(AbstractThread* aThread, const T& aInitialValue, const char* aName)
114
0
  {
115
0
    mImpl = new Impl(aThread, aInitialValue, aName);
116
0
  }
Unexecuted instantiation: mozilla::Canonical<double>::Canonical(mozilla::AbstractThread*, double const&, char const*)
Unexecuted instantiation: mozilla::Canonical<bool>::Canonical(mozilla::AbstractThread*, bool const&, char const*)
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Canonical(mozilla::AbstractThread*, mozilla::MediaDecoder::PlayState const&, char const*)
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Canonical(mozilla::AbstractThread*, nsMainThreadPtrHandle<nsIPrincipal> const&, char const*)
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Canonical(mozilla::AbstractThread*, mozilla::Maybe<mozilla::media::TimeUnit> const&, char const*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Canonical(mozilla::AbstractThread*, mozilla::media::TimeUnit const&, char const*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Canonical(mozilla::AbstractThread*, mozilla::media::TimeIntervals const&, char const*)
117
118
119
0
  ~Canonical() {}
Unexecuted instantiation: mozilla::Canonical<double>::~Canonical()
Unexecuted instantiation: mozilla::Canonical<bool>::~Canonical()
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::~Canonical()
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::~Canonical()
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::~Canonical()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::~Canonical()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::~Canonical()
120
121
private:
122
  class Impl : public AbstractCanonical<T>, public WatchTarget
123
  {
124
  public:
125
    using AbstractCanonical<T>::OwnerThread;
126
127
    Impl(AbstractThread* aThread, const T& aInitialValue, const char* aName)
128
      : AbstractCanonical<T>(aThread), WatchTarget(aName), mValue(aInitialValue)
129
0
    {
130
0
      MIRROR_LOG("%s [%p] initialized", mName, this);
131
0
      MOZ_ASSERT(aThread->SupportsTailDispatch(), "Can't get coherency without tail dispatch");
132
0
    }
Unexecuted instantiation: mozilla::Canonical<double>::Impl::Impl(mozilla::AbstractThread*, double const&, char const*)
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::Impl(mozilla::AbstractThread*, bool const&, char const*)
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl::Impl(mozilla::AbstractThread*, mozilla::MediaDecoder::PlayState const&, char const*)
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::Impl(mozilla::AbstractThread*, nsMainThreadPtrHandle<nsIPrincipal> const&, char const*)
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::Impl(mozilla::AbstractThread*, mozilla::Maybe<mozilla::media::TimeUnit> const&, char const*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::Impl(mozilla::AbstractThread*, mozilla::media::TimeUnit const&, char const*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Impl::Impl(mozilla::AbstractThread*, mozilla::media::TimeIntervals const&, char const*)
133
134
    void AddMirror(AbstractMirror<T>* aMirror) override
135
0
    {
136
0
      MIRROR_LOG("%s [%p] adding mirror %p", mName, this, aMirror);
137
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
138
0
      MOZ_ASSERT(!mMirrors.Contains(aMirror));
139
0
      mMirrors.AppendElement(aMirror);
140
0
      aMirror->OwnerThread()->DispatchStateChange(MakeNotifier(aMirror));
141
0
    }
Unexecuted instantiation: mozilla::Canonical<double>::Impl::AddMirror(mozilla::AbstractMirror<double>*)
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::AddMirror(mozilla::AbstractMirror<bool>*)
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl::AddMirror(mozilla::AbstractMirror<mozilla::MediaDecoder::PlayState>*)
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::AddMirror(mozilla::AbstractMirror<nsMainThreadPtrHandle<nsIPrincipal> >*)
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::AddMirror(mozilla::AbstractMirror<mozilla::Maybe<mozilla::media::TimeUnit> >*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::AddMirror(mozilla::AbstractMirror<mozilla::media::TimeUnit>*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Impl::AddMirror(mozilla::AbstractMirror<mozilla::media::TimeIntervals>*)
142
143
    void RemoveMirror(AbstractMirror<T>* aMirror) override
144
0
    {
145
0
      MIRROR_LOG("%s [%p] removing mirror %p", mName, this, aMirror);
146
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
147
0
      MOZ_ASSERT(mMirrors.Contains(aMirror));
148
0
      mMirrors.RemoveElement(aMirror);
149
0
    }
Unexecuted instantiation: mozilla::Canonical<double>::Impl::RemoveMirror(mozilla::AbstractMirror<double>*)
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::RemoveMirror(mozilla::AbstractMirror<bool>*)
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl::RemoveMirror(mozilla::AbstractMirror<mozilla::MediaDecoder::PlayState>*)
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::RemoveMirror(mozilla::AbstractMirror<nsMainThreadPtrHandle<nsIPrincipal> >*)
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::RemoveMirror(mozilla::AbstractMirror<mozilla::Maybe<mozilla::media::TimeUnit> >*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::RemoveMirror(mozilla::AbstractMirror<mozilla::media::TimeUnit>*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Impl::RemoveMirror(mozilla::AbstractMirror<mozilla::media::TimeIntervals>*)
150
151
    void DisconnectAll()
152
0
    {
153
0
      MIRROR_LOG("%s [%p] Disconnecting all mirrors", mName, this);
154
0
      for (size_t i = 0; i < mMirrors.Length(); ++i) {
155
0
        mMirrors[i]->OwnerThread()->Dispatch(
156
0
          NewRunnableMethod("AbstractMirror::NotifyDisconnected",
157
0
                            mMirrors[i],
158
0
                            &AbstractMirror<T>::NotifyDisconnected));
159
0
      }
160
0
      mMirrors.Clear();
161
0
    }
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::DisconnectAll()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::DisconnectAll()
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::DisconnectAll()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Impl::DisconnectAll()
162
163
    operator const T&()
164
0
    {
165
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
166
0
      return mValue;
167
0
    }
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl::operator mozilla::MediaDecoder::PlayState const&()
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::operator bool const&()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::operator mozilla::media::TimeUnit const&()
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::operator mozilla::Maybe<mozilla::media::TimeUnit> const&()
168
169
    void Set(const T& aNewValue)
170
0
    {
171
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
172
0
173
0
      if (aNewValue == mValue) {
174
0
        return;
175
0
      }
176
0
177
0
      // Notify same-thread watchers. The state watching machinery will make sure
178
0
      // that notifications run at the right time.
179
0
      NotifyWatchers();
180
0
181
0
      // Check if we've already got a pending update. If so we won't schedule another
182
0
      // one.
183
0
      bool alreadyNotifying = mInitialValue.isSome();
184
0
185
0
      // Stash the initial value if needed, then update to the new value.
186
0
      if (mInitialValue.isNothing()) {
187
0
        mInitialValue.emplace(mValue);
188
0
      }
189
0
      mValue = aNewValue;
190
0
191
0
      // We wait until things have stablized before sending state updates so that
192
0
      // we can avoid sending multiple updates, and possibly avoid sending any
193
0
      // updates at all if the value ends up where it started.
194
0
      if (!alreadyNotifying) {
195
0
        AbstractThread::DispatchDirectTask(NewRunnableMethod(
196
0
          "Canonical::Impl::DoNotify", this, &Impl::DoNotify));
197
0
      }
198
0
    }
Unexecuted instantiation: mozilla::Canonical<double>::Impl::Set(double const&)
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::Set(bool const&)
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::Set(nsMainThreadPtrHandle<nsIPrincipal> const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl::Set(mozilla::MediaDecoder::PlayState const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::Set(mozilla::Maybe<mozilla::media::TimeUnit> const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::Set(mozilla::media::TimeUnit const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Impl::Set(mozilla::media::TimeIntervals const&)
199
200
    Impl& operator=(const T& aNewValue) { Set(aNewValue); return *this; }
201
    Impl& operator=(const Impl& aOther) { Set(aOther); return *this; }
202
    Impl(const Impl& aOther) = delete;
203
204
  protected:
205
0
    ~Impl() { MOZ_DIAGNOSTIC_ASSERT(mMirrors.IsEmpty()); }
Unexecuted instantiation: mozilla::Canonical<double>::Impl::~Impl()
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::~Impl()
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl::~Impl()
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::~Impl()
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::~Impl()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::~Impl()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Impl::~Impl()
206
207
  private:
208
    void DoNotify()
209
0
    {
210
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
211
0
      MOZ_ASSERT(mInitialValue.isSome());
212
0
      bool same = mInitialValue.ref() == mValue;
213
0
      mInitialValue.reset();
214
0
215
0
      if (same) {
216
0
        MIRROR_LOG("%s [%p] unchanged - not sending update", mName, this);
217
0
        return;
218
0
      }
219
0
220
0
      for (size_t i = 0; i < mMirrors.Length(); ++i) {
221
0
        mMirrors[i]->OwnerThread()->DispatchStateChange(MakeNotifier(mMirrors[i]));
222
0
      }
223
0
    }
Unexecuted instantiation: mozilla::Canonical<double>::Impl::DoNotify()
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::DoNotify()
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::DoNotify()
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl::DoNotify()
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::DoNotify()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::DoNotify()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Impl::DoNotify()
224
225
    already_AddRefed<nsIRunnable> MakeNotifier(AbstractMirror<T>* aMirror)
226
0
    {
227
0
      return NewRunnableMethod<T>("AbstractMirror::UpdateValue",
228
0
                                  aMirror,
229
0
                                  &AbstractMirror<T>::UpdateValue,
230
0
                                  mValue);
231
0
      ;
232
0
    }
Unexecuted instantiation: mozilla::Canonical<double>::Impl::MakeNotifier(mozilla::AbstractMirror<double>*)
Unexecuted instantiation: mozilla::Canonical<bool>::Impl::MakeNotifier(mozilla::AbstractMirror<bool>*)
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl::MakeNotifier(mozilla::AbstractMirror<mozilla::MediaDecoder::PlayState>*)
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::MakeNotifier(mozilla::AbstractMirror<nsMainThreadPtrHandle<nsIPrincipal> >*)
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::MakeNotifier(mozilla::AbstractMirror<mozilla::Maybe<mozilla::media::TimeUnit> >*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Impl::MakeNotifier(mozilla::AbstractMirror<mozilla::media::TimeUnit>*)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Impl::MakeNotifier(mozilla::AbstractMirror<mozilla::media::TimeIntervals>*)
233
234
    T mValue;
235
    Maybe<T> mInitialValue;
236
    nsTArray<RefPtr<AbstractMirror<T>>> mMirrors;
237
  };
238
public:
239
240
  // NB: Because mirror-initiated disconnection can race with canonical-
241
  // initiated disconnection, a canonical should never be reinitialized.
242
  // Forward control operations to the Impl.
243
0
  void DisconnectAll() { return mImpl->DisconnectAll(); }
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::DisconnectAll()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::DisconnectAll()
Unexecuted instantiation: mozilla::Canonical<bool>::DisconnectAll()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::DisconnectAll()
244
245
  // Access to the Impl.
246
0
  operator Impl&() { return *mImpl; }
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::operator mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Impl&()
Unexecuted instantiation: mozilla::Canonical<bool>::operator mozilla::Canonical<bool>::Impl&()
247
0
  Impl* operator&() { return mImpl; }
Unexecuted instantiation: mozilla::Canonical<double>::operator&()
Unexecuted instantiation: mozilla::Canonical<bool>::operator&()
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::operator&()
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::operator&()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::operator&()
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::operator&()
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::operator&()
248
249
  // Access to the T.
250
0
  const T& Ref() const { return *mImpl; }
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Ref() const
Unexecuted instantiation: mozilla::Canonical<bool>::Ref() const
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Ref() const
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Ref() const
251
0
  operator const T&() const { return Ref(); }
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::operator mozilla::MediaDecoder::PlayState const&() const
Unexecuted instantiation: mozilla::Canonical<bool>::operator bool const&() const
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::operator mozilla::media::TimeUnit const&() const
252
0
  void Set(const T& aNewValue) { mImpl->Set(aNewValue); }
Unexecuted instantiation: mozilla::Canonical<double>::Set(double const&)
Unexecuted instantiation: mozilla::Canonical<bool>::Set(bool const&)
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::Set(nsMainThreadPtrHandle<nsIPrincipal> const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::Set(mozilla::MediaDecoder::PlayState const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::Set(mozilla::Maybe<mozilla::media::TimeUnit> const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::Set(mozilla::media::TimeUnit const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::Set(mozilla::media::TimeIntervals const&)
253
0
  Canonical& operator=(const T& aNewValue) { Set(aNewValue); return *this; }
Unexecuted instantiation: mozilla::Canonical<double>::operator=(double const&)
Unexecuted instantiation: mozilla::Canonical<bool>::operator=(bool const&)
Unexecuted instantiation: mozilla::Canonical<nsMainThreadPtrHandle<nsIPrincipal> >::operator=(nsMainThreadPtrHandle<nsIPrincipal> const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::MediaDecoder::PlayState>::operator=(mozilla::MediaDecoder::PlayState const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::Maybe<mozilla::media::TimeUnit> >::operator=(mozilla::Maybe<mozilla::media::TimeUnit> const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeUnit>::operator=(mozilla::media::TimeUnit const&)
Unexecuted instantiation: mozilla::Canonical<mozilla::media::TimeIntervals>::operator=(mozilla::media::TimeIntervals const&)
254
  Canonical& operator=(const Canonical& aOther) { Set(aOther); return *this; }
255
  Canonical(const Canonical& aOther) = delete;
256
257
private:
258
  RefPtr<Impl> mImpl;
259
};
260
261
/*
262
 * Mirror<T> is a wrapper class that allows a given value to mirror that of a
263
 * Canonical<T> owned by another thread. It registers itself with a Canonical<T>,
264
 * and is periodically updated with new values. Mirror<T> is also a WatchTarget,
265
 * and may be set up to trigger other routines (on the same thread) when the
266
 * mirrored value changes.
267
 *
268
 * Mirror<T> is intended to be used as a member variable, so it doesn't actually
269
 * inherit AbstractMirror<T> (a refcounted type). Rather, it contains an inner
270
 * class called |Impl| that implements most of the interesting logic.
271
 */
272
template<typename T>
273
class Mirror
274
{
275
public:
276
  Mirror(AbstractThread* aThread, const T& aInitialValue, const char* aName)
277
0
  {
278
0
    mImpl = new Impl(aThread, aInitialValue, aName);
279
0
  }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Mirror(mozilla::AbstractThread*, mozilla::media::TimeIntervals const&, char const*)
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Mirror(mozilla::AbstractThread*, mozilla::media::TimeUnit const&, char const*)
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Mirror(mozilla::AbstractThread*, mozilla::Maybe<mozilla::media::TimeUnit> const&, char const*)
Unexecuted instantiation: mozilla::Mirror<bool>::Mirror(mozilla::AbstractThread*, bool const&, char const*)
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Mirror(mozilla::AbstractThread*, mozilla::MediaDecoder::PlayState const&, char const*)
Unexecuted instantiation: mozilla::Mirror<double>::Mirror(mozilla::AbstractThread*, double const&, char const*)
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Mirror(mozilla::AbstractThread*, nsMainThreadPtrHandle<nsIPrincipal> const&, char const*)
280
281
  ~Mirror()
282
0
  {
283
0
    // As a member of complex objects, a Mirror<T> may be destroyed on a
284
0
    // different thread than its owner, or late in shutdown during CC. Given
285
0
    // that, we require manual disconnection so that callers can put things in
286
0
    // the right place.
287
0
    MOZ_DIAGNOSTIC_ASSERT(!mImpl->IsConnected());
288
0
  }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::~Mirror()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::~Mirror()
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::~Mirror()
Unexecuted instantiation: mozilla::Mirror<bool>::~Mirror()
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::~Mirror()
Unexecuted instantiation: mozilla::Mirror<double>::~Mirror()
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::~Mirror()
289
290
private:
291
  class Impl : public AbstractMirror<T>, public WatchTarget
292
  {
293
  public:
294
    using AbstractMirror<T>::OwnerThread;
295
296
    Impl(AbstractThread* aThread, const T& aInitialValue, const char* aName)
297
      : AbstractMirror<T>(aThread), WatchTarget(aName), mValue(aInitialValue)
298
0
    {
299
0
      MIRROR_LOG("%s [%p] initialized", mName, this);
300
0
      MOZ_ASSERT(aThread->SupportsTailDispatch(), "Can't get coherency without tail dispatch");
301
0
    }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Impl::Impl(mozilla::AbstractThread*, mozilla::media::TimeIntervals const&, char const*)
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Impl::Impl(mozilla::AbstractThread*, mozilla::media::TimeUnit const&, char const*)
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::Impl(mozilla::AbstractThread*, mozilla::Maybe<mozilla::media::TimeUnit> const&, char const*)
Unexecuted instantiation: mozilla::Mirror<bool>::Impl::Impl(mozilla::AbstractThread*, bool const&, char const*)
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl::Impl(mozilla::AbstractThread*, mozilla::MediaDecoder::PlayState const&, char const*)
Unexecuted instantiation: mozilla::Mirror<double>::Impl::Impl(mozilla::AbstractThread*, double const&, char const*)
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::Impl(mozilla::AbstractThread*, nsMainThreadPtrHandle<nsIPrincipal> const&, char const*)
302
303
    operator const T&()
304
0
    {
305
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
306
0
      return mValue;
307
0
    }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Impl::operator mozilla::media::TimeUnit const&()
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::operator mozilla::Maybe<mozilla::media::TimeUnit> const&()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Impl::operator mozilla::media::TimeIntervals const&()
Unexecuted instantiation: mozilla::Mirror<bool>::Impl::operator bool const&()
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::operator nsMainThreadPtrHandle<nsIPrincipal> const&()
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl::operator mozilla::MediaDecoder::PlayState const&()
Unexecuted instantiation: mozilla::Mirror<double>::Impl::operator double const&()
308
309
    virtual void UpdateValue(const T& aNewValue) override
310
0
    {
311
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
312
0
      if (mValue != aNewValue) {
313
0
        mValue = aNewValue;
314
0
        WatchTarget::NotifyWatchers();
315
0
      }
316
0
    }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Impl::UpdateValue(mozilla::media::TimeIntervals const&)
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Impl::UpdateValue(mozilla::media::TimeUnit const&)
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::UpdateValue(mozilla::Maybe<mozilla::media::TimeUnit> const&)
Unexecuted instantiation: mozilla::Mirror<bool>::Impl::UpdateValue(bool const&)
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl::UpdateValue(mozilla::MediaDecoder::PlayState const&)
Unexecuted instantiation: mozilla::Mirror<double>::Impl::UpdateValue(double const&)
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::UpdateValue(nsMainThreadPtrHandle<nsIPrincipal> const&)
317
318
    virtual void NotifyDisconnected() override
319
0
    {
320
0
      MIRROR_LOG("%s [%p] Notifed of disconnection from %p", mName, this, mCanonical.get());
321
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
322
0
      mCanonical = nullptr;
323
0
    }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Impl::NotifyDisconnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Impl::NotifyDisconnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::NotifyDisconnected()
Unexecuted instantiation: mozilla::Mirror<bool>::Impl::NotifyDisconnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl::NotifyDisconnected()
Unexecuted instantiation: mozilla::Mirror<double>::Impl::NotifyDisconnected()
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::NotifyDisconnected()
324
325
0
    bool IsConnected() const { return !!mCanonical; }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Impl::IsConnected() const
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Impl::IsConnected() const
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::IsConnected() const
Unexecuted instantiation: mozilla::Mirror<bool>::Impl::IsConnected() const
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl::IsConnected() const
Unexecuted instantiation: mozilla::Mirror<double>::Impl::IsConnected() const
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::IsConnected() const
326
327
    void Connect(AbstractCanonical<T>* aCanonical)
328
0
    {
329
0
      MIRROR_LOG("%s [%p] Connecting to %p", mName, this, aCanonical);
330
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
331
0
      MOZ_ASSERT(!IsConnected());
332
0
      MOZ_ASSERT(OwnerThread()->RequiresTailDispatch(aCanonical->OwnerThread()), "Can't get coherency without tail dispatch");
333
0
334
0
      nsCOMPtr<nsIRunnable> r =
335
0
        NewRunnableMethod<StoreRefPtrPassByPtr<AbstractMirror<T>>>(
336
0
          "AbstractCanonical::AddMirror",
337
0
          aCanonical,
338
0
          &AbstractCanonical<T>::AddMirror,
339
0
          this);
340
0
      aCanonical->OwnerThread()->Dispatch(r.forget());
341
0
      mCanonical = aCanonical;
342
0
    }
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::Connect(mozilla::AbstractCanonical<mozilla::Maybe<mozilla::media::TimeUnit> >*)
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Impl::Connect(mozilla::AbstractCanonical<mozilla::media::TimeIntervals>*)
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Impl::Connect(mozilla::AbstractCanonical<mozilla::media::TimeUnit>*)
Unexecuted instantiation: mozilla::Mirror<bool>::Impl::Connect(mozilla::AbstractCanonical<bool>*)
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl::Connect(mozilla::AbstractCanonical<mozilla::MediaDecoder::PlayState>*)
Unexecuted instantiation: mozilla::Mirror<double>::Impl::Connect(mozilla::AbstractCanonical<double>*)
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::Connect(mozilla::AbstractCanonical<nsMainThreadPtrHandle<nsIPrincipal> >*)
343
  public:
344
345
    void DisconnectIfConnected()
346
0
    {
347
0
      MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
348
0
      if (!IsConnected()) {
349
0
        return;
350
0
      }
351
0
352
0
      MIRROR_LOG("%s [%p] Disconnecting from %p", mName, this, mCanonical.get());
353
0
      nsCOMPtr<nsIRunnable> r =
354
0
        NewRunnableMethod<StoreRefPtrPassByPtr<AbstractMirror<T>>>(
355
0
          "AbstractCanonical::RemoveMirror",
356
0
          mCanonical,
357
0
          &AbstractCanonical<T>::RemoveMirror,
358
0
          this);
359
0
      mCanonical->OwnerThread()->Dispatch(r.forget());
360
0
      mCanonical = nullptr;
361
0
    }
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Impl::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Impl::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<bool>::Impl::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<double>::Impl::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::DisconnectIfConnected()
362
363
  protected:
364
0
    ~Impl() { MOZ_DIAGNOSTIC_ASSERT(!IsConnected()); }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Impl::~Impl()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Impl::~Impl()
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl::~Impl()
Unexecuted instantiation: mozilla::Mirror<bool>::Impl::~Impl()
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl::~Impl()
Unexecuted instantiation: mozilla::Mirror<double>::Impl::~Impl()
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Impl::~Impl()
365
366
  private:
367
    T mValue;
368
    RefPtr<AbstractCanonical<T>> mCanonical;
369
  };
370
public:
371
372
  // Forward control operations to the Impl<T>.
373
0
  void Connect(AbstractCanonical<T>* aCanonical) { mImpl->Connect(aCanonical); }
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Connect(mozilla::AbstractCanonical<mozilla::Maybe<mozilla::media::TimeUnit> >*)
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Connect(mozilla::AbstractCanonical<mozilla::media::TimeIntervals>*)
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Connect(mozilla::AbstractCanonical<mozilla::media::TimeUnit>*)
Unexecuted instantiation: mozilla::Mirror<bool>::Connect(mozilla::AbstractCanonical<bool>*)
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Connect(mozilla::AbstractCanonical<mozilla::MediaDecoder::PlayState>*)
Unexecuted instantiation: mozilla::Mirror<double>::Connect(mozilla::AbstractCanonical<double>*)
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Connect(mozilla::AbstractCanonical<nsMainThreadPtrHandle<nsIPrincipal> >*)
374
0
  void DisconnectIfConnected() { mImpl->DisconnectIfConnected(); }
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<bool>::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<double>::DisconnectIfConnected()
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::DisconnectIfConnected()
375
376
  // Access to the Impl<T>.
377
0
  operator Impl&() { return *mImpl; }
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::operator mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Impl&()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::operator mozilla::Mirror<mozilla::media::TimeIntervals>::Impl&()
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::operator mozilla::Mirror<mozilla::media::TimeUnit>::Impl&()
Unexecuted instantiation: mozilla::Mirror<bool>::operator mozilla::Mirror<bool>::Impl&()
Unexecuted instantiation: mozilla::Mirror<double>::operator mozilla::Mirror<double>::Impl&()
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::operator mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Impl&()
378
  Impl* operator&() { return mImpl; }
379
380
  // Access to the T.
381
0
  const T& Ref() const { return *mImpl; }
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeUnit>::Ref() const
Unexecuted instantiation: mozilla::Mirror<mozilla::Maybe<mozilla::media::TimeUnit> >::Ref() const
Unexecuted instantiation: mozilla::Mirror<mozilla::media::TimeIntervals>::Ref() const
Unexecuted instantiation: mozilla::Mirror<bool>::Ref() const
Unexecuted instantiation: mozilla::Mirror<nsMainThreadPtrHandle<nsIPrincipal> >::Ref() const
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::Ref() const
Unexecuted instantiation: mozilla::Mirror<double>::Ref() const
382
0
  operator const T&() const { return Ref(); }
Unexecuted instantiation: mozilla::Mirror<bool>::operator bool const&() const
Unexecuted instantiation: mozilla::Mirror<mozilla::MediaDecoder::PlayState>::operator mozilla::MediaDecoder::PlayState const&() const
Unexecuted instantiation: mozilla::Mirror<double>::operator double const&() const
383
384
private:
385
  RefPtr<Impl> mImpl;
386
};
387
388
#undef MIRROR_LOG
389
390
} // namespace mozilla
391
392
#endif