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 : 184750cfde201ef0ce7e70301761e3e51e82b3a3
This commit is contained in:
Doug Thayer 2018-06-29 15:27:22 -07:00
Родитель e166b5a5e9
Коммит f460428e9c
5 изменённых файлов: 173 добавлений и 20 удалений

129
xpcom/base/StaticMonitor.h Normal file
Просмотреть файл

@ -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

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

@ -119,6 +119,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

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

@ -105,7 +105,7 @@ private:
OffTheBooksMutex(const OffTheBooksMutex&);
OffTheBooksMutex& operator=(const OffTheBooksMutex&);
friend class CondVar;
friend class OffTheBooksCondVar;
#ifdef DEBUG
PRThread* mOwningThread;