Bug 857895 - Only enforce tail dispatch if both source and dest support it. r=bholley

This commit is contained in:
Matt Woodrow 2015-05-14 13:47:42 +12:00
Родитель 368aba9ea0
Коммит 924056f5e8
4 изменённых файлов: 21 добавлений и 8 удалений

Просмотреть файл

@ -51,7 +51,7 @@ public:
{ {
nsCOMPtr<nsIRunnable> r = aRunnable; nsCOMPtr<nsIRunnable> r = aRunnable;
AbstractThread* currentThread; AbstractThread* currentThread;
if (aReason != TailDispatch && (currentThread = GetCurrent()) && currentThread->RequiresTailDispatch()) { if (aReason != TailDispatch && (currentThread = GetCurrent()) && RequiresTailDispatch(currentThread)) {
currentThread->TailDispatcher().AddTask(this, r.forget(), aFailureHandling); currentThread->TailDispatcher().AddTask(this, r.forget(), aFailureHandling);
return; return;
} }
@ -101,6 +101,14 @@ private:
Maybe<AutoTaskDispatcher> mTailDispatcher; Maybe<AutoTaskDispatcher> mTailDispatcher;
}; };
bool
AbstractThread::RequiresTailDispatch(AbstractThread* aThread) const
{
// We require tail dispatch if both the source and destination
// threads support it.
return SupportsTailDispatch() && aThread->SupportsTailDispatch();
}
AbstractThread* AbstractThread*
AbstractThread::MainThread() AbstractThread::MainThread()
{ {

Просмотреть файл

@ -40,7 +40,7 @@ public:
// if the caller is not running in an AbstractThread. // if the caller is not running in an AbstractThread.
static AbstractThread* GetCurrent() { return sCurrentThreadTLS.get(); } static AbstractThread* GetCurrent() { return sCurrentThreadTLS.get(); }
AbstractThread(bool aRequireTailDispatch) : mRequireTailDispatch(aRequireTailDispatch) {} AbstractThread(bool aSupportsTailDispatch) : mSupportsTailDispatch(aSupportsTailDispatch) {}
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractThread); NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractThread);
@ -63,9 +63,12 @@ public:
// threads which support it. // threads which support it.
virtual TaskDispatcher& TailDispatcher() = 0; virtual TaskDispatcher& TailDispatcher() = 0;
// Returns true if this task queue requires all dispatches performed by its // Returns true if this supports the tail dispatcher.
// tasks to go through the tail dispatcher. bool SupportsTailDispatch() const { return mSupportsTailDispatch; }
bool RequiresTailDispatch() const { return mRequireTailDispatch; }
// Returns true if this thread requires all dispatches originating from
// aThread go through the tail dispatcher.
bool RequiresTailDispatch(AbstractThread* aThread) const;
virtual MediaTaskQueue* AsTaskQueue() { MOZ_CRASH("Not a task queue!"); } virtual MediaTaskQueue* AsTaskQueue() { MOZ_CRASH("Not a task queue!"); }
virtual nsIThread* AsXPCOMThread() { MOZ_CRASH("Not an XPCOM thread!"); } virtual nsIThread* AsXPCOMThread() { MOZ_CRASH("Not an XPCOM thread!"); }
@ -82,7 +85,7 @@ protected:
// True if we want to require that every task dispatched from tasks running in // True if we want to require that every task dispatched from tasks running in
// this queue go through our queue's tail dispatcher. // this queue go through our queue's tail dispatcher.
const bool mRequireTailDispatch; const bool mSupportsTailDispatch;
}; };
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -45,7 +45,7 @@ MediaTaskQueue::DispatchLocked(already_AddRefed<nsIRunnable> aRunnable,
{ {
nsCOMPtr<nsIRunnable> r = aRunnable; nsCOMPtr<nsIRunnable> r = aRunnable;
AbstractThread* currentThread; AbstractThread* currentThread;
if (aReason != TailDispatch && (currentThread = GetCurrent()) && currentThread->RequiresTailDispatch()) { if (aReason != TailDispatch && (currentThread = GetCurrent()) && RequiresTailDispatch(currentThread)) {
currentThread->TailDispatcher().AddTask(this, r.forget(), aFailureHandling); currentThread->TailDispatcher().AddTask(this, r.forget(), aFailureHandling);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -130,7 +130,7 @@ private:
: AbstractCanonical<T>(aThread), WatchTarget(aName), mValue(aInitialValue) : AbstractCanonical<T>(aThread), WatchTarget(aName), mValue(aInitialValue)
{ {
MIRROR_LOG("%s [%p] initialized", mName, this); MIRROR_LOG("%s [%p] initialized", mName, this);
MOZ_ASSERT(aThread->RequiresTailDispatch(), "Can't get coherency without tail dispatch"); MOZ_ASSERT(aThread->SupportsTailDispatch(), "Can't get coherency without tail dispatch");
} }
void AddMirror(AbstractMirror<T>* aMirror) override void AddMirror(AbstractMirror<T>* aMirror) override
@ -303,6 +303,7 @@ private:
: AbstractMirror<T>(aThread), WatchTarget(aName), mValue(aInitialValue) : AbstractMirror<T>(aThread), WatchTarget(aName), mValue(aInitialValue)
{ {
MIRROR_LOG("%s [%p] initialized", mName, this); MIRROR_LOG("%s [%p] initialized", mName, this);
MOZ_ASSERT(aThread->SupportsTailDispatch(), "Can't get coherency without tail dispatch");
} }
operator const T&() operator const T&()
@ -334,6 +335,7 @@ private:
MIRROR_LOG("%s [%p] Connecting to %p", mName, this, aCanonical); MIRROR_LOG("%s [%p] Connecting to %p", mName, this, aCanonical);
MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn()); MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
MOZ_ASSERT(!IsConnected()); MOZ_ASSERT(!IsConnected());
MOZ_ASSERT(OwnerThread()->RequiresTailDispatch(aCanonical->OwnerThread()), "Can't get coherency without tail dispatch");
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<StorensRefPtrPassByPtr<AbstractMirror<T>>> nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<StorensRefPtrPassByPtr<AbstractMirror<T>>>
(aCanonical, &AbstractCanonical<T>::AddMirror, this); (aCanonical, &AbstractCanonical<T>::AddMirror, this);