зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1265824 - Add StaticMonitor r=froydnj
For the IPC work monitoring when textures become unlocked, we need a Monitor equivalent of StaticMutex - this implements that. MozReview-Commit-ID: IceQNeqVQ8f --HG-- extra : rebase_source : 40b3f6f4934b83d28005722cf13b717ff81ef697
This commit is contained in:
Родитель
dc533418d3
Коммит
8911034486
|
@ -0,0 +1,129 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_StaticMonitor_h
|
||||
#define mozilla_StaticMonitor_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS StaticMonitor
|
||||
{
|
||||
public:
|
||||
// In debug builds, check that mMutex is initialized for us as we expect by
|
||||
// the compiler. In non-debug builds, don't declare a constructor so that
|
||||
// the compiler can see that the constructor is trivial.
|
||||
#ifdef DEBUG
|
||||
StaticMonitor()
|
||||
{
|
||||
MOZ_ASSERT(!mMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Lock()
|
||||
{
|
||||
Mutex()->Lock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
Mutex()->Unlock();
|
||||
}
|
||||
|
||||
void Wait() { CondVar()->Wait(); }
|
||||
CVStatus Wait(TimeDuration aDuration) { return CondVar()->Wait(aDuration); }
|
||||
|
||||
nsresult Notify() { return CondVar()->Notify(); }
|
||||
nsresult NotifyAll() { return CondVar()->NotifyAll(); }
|
||||
|
||||
void AssertCurrentThreadOwns()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Mutex()->AssertCurrentThreadOwns();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
OffTheBooksMutex* Mutex()
|
||||
{
|
||||
if (mMutex) {
|
||||
return mMutex;
|
||||
}
|
||||
|
||||
OffTheBooksMutex* mutex = new OffTheBooksMutex("StaticMutex");
|
||||
if (!mMutex.compareExchange(nullptr, mutex)) {
|
||||
delete mutex;
|
||||
}
|
||||
|
||||
return mMutex;
|
||||
}
|
||||
|
||||
OffTheBooksCondVar* CondVar()
|
||||
{
|
||||
if (mCondVar) {
|
||||
return mCondVar;
|
||||
}
|
||||
|
||||
OffTheBooksCondVar* condvar = new OffTheBooksCondVar(*Mutex(), "StaticCondVar");
|
||||
if (!mCondVar.compareExchange(nullptr, condvar)) {
|
||||
delete condvar;
|
||||
}
|
||||
|
||||
return mCondVar;
|
||||
}
|
||||
|
||||
Atomic<OffTheBooksMutex*> mMutex;
|
||||
Atomic<OffTheBooksCondVar*> mCondVar;
|
||||
|
||||
|
||||
// Disallow copy constructor, but only in debug mode. We only define
|
||||
// a default constructor in debug mode (see above); if we declared
|
||||
// this constructor always, the compiler wouldn't generate a trivial
|
||||
// default constructor for us in non-debug mode.
|
||||
#ifdef DEBUG
|
||||
StaticMonitor(const StaticMonitor& aOther);
|
||||
#endif
|
||||
|
||||
// Disallow these operators.
|
||||
StaticMonitor& operator=(const StaticMonitor& aRhs);
|
||||
static void* operator new(size_t) CPP_THROW_NEW;
|
||||
static void operator delete(void*);
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS StaticMonitorAutoLock
|
||||
{
|
||||
public:
|
||||
explicit StaticMonitorAutoLock(StaticMonitor& aMonitor)
|
||||
: mMonitor(&aMonitor)
|
||||
{
|
||||
mMonitor->Lock();
|
||||
}
|
||||
|
||||
~StaticMonitorAutoLock()
|
||||
{
|
||||
mMonitor->Unlock();
|
||||
}
|
||||
|
||||
void Wait() { mMonitor->Wait(); }
|
||||
CVStatus Wait(TimeDuration aDuration) { return mMonitor->Wait(aDuration); }
|
||||
|
||||
nsresult Notify() { return mMonitor->Notify(); }
|
||||
nsresult NotifyAll() { return mMonitor->NotifyAll(); }
|
||||
|
||||
private:
|
||||
StaticMonitorAutoLock();
|
||||
StaticMonitorAutoLock(const StaticMonitorAutoLock&);
|
||||
StaticMonitorAutoLock& operator=(const StaticMonitorAutoLock&);
|
||||
static void* operator new(size_t) CPP_THROW_NEW;
|
||||
|
||||
StaticMonitor* mMonitor;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -117,6 +117,7 @@ EXPORTS.mozilla += [
|
|||
'NSPRLogModulesParser.h',
|
||||
'OwningNonNull.h',
|
||||
'SizeOfState.h',
|
||||
'StaticMonitor.h',
|
||||
'StaticMutex.h',
|
||||
'StaticPtr.h',
|
||||
]
|
||||
|
|
|
@ -587,15 +587,15 @@ RecursiveMutex::AssertCurrentThreadIn()
|
|||
//
|
||||
// Debug implementation of CondVar
|
||||
void
|
||||
CondVar::Wait()
|
||||
OffTheBooksCondVar::Wait()
|
||||
{
|
||||
// Forward to the timed version of CondVar::Wait to avoid code duplication.
|
||||
// Forward to the timed version of OffTheBooksCondVar::Wait to avoid code duplication.
|
||||
CVStatus status = Wait(TimeDuration::Forever());
|
||||
MOZ_ASSERT(status == CVStatus::NoTimeout);
|
||||
}
|
||||
|
||||
CVStatus
|
||||
CondVar::Wait(TimeDuration aDuration)
|
||||
OffTheBooksCondVar::Wait(TimeDuration aDuration)
|
||||
{
|
||||
AssertCurrentThreadOwnsMutex();
|
||||
|
||||
|
|
|
@ -17,17 +17,17 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
|
||||
/**
|
||||
* CondVar
|
||||
* Vanilla condition variable. Please don't use this unless you have a
|
||||
* compelling reason --- Monitor provides a simpler API.
|
||||
* Similarly to OffTheBooksMutex, OffTheBooksCondvar is identical to CondVar,
|
||||
* except that OffTheBooksCondVar doesn't include leak checking. Sometimes
|
||||
* you want to intentionally "leak" a CondVar until shutdown; in these cases,
|
||||
* OffTheBooksCondVar is for you.
|
||||
*/
|
||||
class CondVar : BlockingResourceBase
|
||||
class OffTheBooksCondVar : BlockingResourceBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* CondVar
|
||||
* OffTheBooksCondVar
|
||||
*
|
||||
* The CALLER owns |aLock|.
|
||||
*
|
||||
|
@ -37,20 +37,18 @@ public:
|
|||
* If success, a valid Monitor* which must be destroyed
|
||||
* by Monitor::DestroyMonitor()
|
||||
**/
|
||||
CondVar(Mutex& aLock, const char* aName)
|
||||
OffTheBooksCondVar(OffTheBooksMutex& aLock, const char* aName)
|
||||
: BlockingResourceBase(aName, eCondVar)
|
||||
, mLock(&aLock)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CondVar);
|
||||
}
|
||||
|
||||
/**
|
||||
* ~CondVar
|
||||
* Clean up after this CondVar, but NOT its associated Mutex.
|
||||
* ~OffTheBooksCondVar
|
||||
* Clean up after this OffTheBooksCondVar, but NOT its associated Mutex.
|
||||
**/
|
||||
~CondVar()
|
||||
~OffTheBooksCondVar()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CondVar);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,14 +123,39 @@ public:
|
|||
#endif // ifdef DEBUG
|
||||
|
||||
private:
|
||||
CondVar();
|
||||
CondVar(const CondVar&) = delete;
|
||||
CondVar& operator=(const CondVar&) = delete;
|
||||
OffTheBooksCondVar();
|
||||
OffTheBooksCondVar(const OffTheBooksCondVar&) = delete;
|
||||
OffTheBooksCondVar& operator=(const OffTheBooksCondVar&) = delete;
|
||||
|
||||
Mutex* mLock;
|
||||
OffTheBooksMutex* mLock;
|
||||
detail::ConditionVariableImpl mImpl;
|
||||
};
|
||||
|
||||
/**
|
||||
* CondVar
|
||||
* Vanilla condition variable. Please don't use this unless you have a
|
||||
* compelling reason --- Monitor provides a simpler API.
|
||||
*/
|
||||
class CondVar : public OffTheBooksCondVar
|
||||
{
|
||||
public:
|
||||
CondVar(OffTheBooksMutex& aLock, const char* aName)
|
||||
: OffTheBooksCondVar(aLock, aName)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CondVar);
|
||||
}
|
||||
|
||||
~CondVar()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CondVar);
|
||||
}
|
||||
|
||||
private:
|
||||
CondVar();
|
||||
CondVar(const CondVar&);
|
||||
CondVar& operator=(const CondVar&);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ private:
|
|||
OffTheBooksMutex(const OffTheBooksMutex&);
|
||||
OffTheBooksMutex& operator=(const OffTheBooksMutex&);
|
||||
|
||||
friend class CondVar;
|
||||
friend class OffTheBooksCondVar;
|
||||
|
||||
#ifdef DEBUG
|
||||
PRThread* mOwningThread;
|
||||
|
|
Загрузка…
Ссылка в новой задаче