forked from mirrors/gecko-dev
Bug 1121297 (Part 2) - Make VolatileBuffer threadsafe. r=glandium
This commit is contained in:
parent
26bd4c1cb6
commit
fb673b7c3a
5 changed files with 46 additions and 8 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
#define mozalloc_VolatileBuffer_h
|
#define mozalloc_VolatileBuffer_h
|
||||||
|
|
||||||
#include "mozilla/mozalloc.h"
|
#include "mozilla/mozalloc.h"
|
||||||
|
#include "mozilla/Mutex.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
|
||||||
|
|
@ -36,19 +37,19 @@
|
||||||
* When a buffer is purged, some or all of the buffer is zeroed out. This
|
* When a buffer is purged, some or all of the buffer is zeroed out. This
|
||||||
* API cannot tell which parts of the buffer were lost.
|
* API cannot tell which parts of the buffer were lost.
|
||||||
*
|
*
|
||||||
* VolatileBuffer is not thread safe. Do not use VolatileBufferPtrs on
|
* VolatileBuffer and VolatileBufferPtr are threadsafe.
|
||||||
* different threads.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class VolatileBuffer : public RefCounted<VolatileBuffer>
|
class VolatileBuffer
|
||||||
{
|
{
|
||||||
friend class VolatileBufferPtr_base;
|
friend class VolatileBufferPtr_base;
|
||||||
public:
|
public:
|
||||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(VolatileBuffer)
|
MOZ_DECLARE_REFCOUNTED_TYPENAME(VolatileBuffer)
|
||||||
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VolatileBuffer)
|
||||||
|
|
||||||
VolatileBuffer();
|
VolatileBuffer();
|
||||||
~VolatileBuffer();
|
|
||||||
|
|
||||||
/* aAlignment must be a multiple of the pointer size */
|
/* aAlignment must be a multiple of the pointer size */
|
||||||
bool Init(size_t aSize, size_t aAlignment = sizeof(void*));
|
bool Init(size_t aSize, size_t aAlignment = sizeof(void*));
|
||||||
|
|
@ -62,6 +63,15 @@ protected:
|
||||||
void Unlock();
|
void Unlock();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
~VolatileBuffer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protects mLockCount, mFirstLock, and changes to the volatility of our
|
||||||
|
* buffer. Other member variables are read-only except in Init() and the
|
||||||
|
* destructor.
|
||||||
|
*/
|
||||||
|
Mutex mMutex;
|
||||||
|
|
||||||
void* mBuf;
|
void* mBuf;
|
||||||
size_t mSize;
|
size_t mSize;
|
||||||
int mLockCount;
|
int mLockCount;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size);
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
VolatileBuffer::VolatileBuffer()
|
VolatileBuffer::VolatileBuffer()
|
||||||
: mBuf(nullptr)
|
: mMutex("VolatileBuffer")
|
||||||
|
, mBuf(nullptr)
|
||||||
, mSize(0)
|
, mSize(0)
|
||||||
, mLockCount(0)
|
, mLockCount(0)
|
||||||
, mFd(-1)
|
, mFd(-1)
|
||||||
|
|
@ -72,6 +73,8 @@ heap_alloc:
|
||||||
|
|
||||||
VolatileBuffer::~VolatileBuffer()
|
VolatileBuffer::~VolatileBuffer()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mLockCount == 0, "Being destroyed with non-zero lock count?");
|
||||||
|
|
||||||
if (OnHeap()) {
|
if (OnHeap()) {
|
||||||
free(mBuf);
|
free(mBuf);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -83,6 +86,8 @@ VolatileBuffer::~VolatileBuffer()
|
||||||
bool
|
bool
|
||||||
VolatileBuffer::Lock(void** aBuf)
|
VolatileBuffer::Lock(void** aBuf)
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
|
MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
|
||||||
|
|
||||||
*aBuf = mBuf;
|
*aBuf = mBuf;
|
||||||
|
|
@ -98,6 +103,8 @@ VolatileBuffer::Lock(void** aBuf)
|
||||||
void
|
void
|
||||||
VolatileBuffer::Unlock()
|
VolatileBuffer::Unlock()
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
|
MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
|
||||||
if (--mLockCount || OnHeap()) {
|
if (--mLockCount || OnHeap()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ int posix_memalign(void** memptr, size_t alignment, size_t size);
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
VolatileBuffer::VolatileBuffer()
|
VolatileBuffer::VolatileBuffer()
|
||||||
: mBuf(nullptr)
|
: mMutex("VolatileBuffer")
|
||||||
|
, mBuf(nullptr)
|
||||||
, mSize(0)
|
, mSize(0)
|
||||||
, mLockCount(0)
|
, mLockCount(0)
|
||||||
{
|
{
|
||||||
|
|
@ -42,12 +43,16 @@ bool VolatileBuffer::Init(size_t aSize, size_t aAlignment)
|
||||||
|
|
||||||
VolatileBuffer::~VolatileBuffer()
|
VolatileBuffer::~VolatileBuffer()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mLockCount == 0, "Being destroyed with non-zero lock count?");
|
||||||
|
|
||||||
free(mBuf);
|
free(mBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
VolatileBuffer::Lock(void** aBuf)
|
VolatileBuffer::Lock(void** aBuf)
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
|
MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
|
||||||
|
|
||||||
*aBuf = mBuf;
|
*aBuf = mBuf;
|
||||||
|
|
@ -59,6 +64,8 @@ VolatileBuffer::Lock(void** aBuf)
|
||||||
void
|
void
|
||||||
VolatileBuffer::Unlock()
|
VolatileBuffer::Unlock()
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
mLockCount--;
|
mLockCount--;
|
||||||
MOZ_ASSERT(mLockCount >= 0, "VolatileBuffer unlocked too many times!");
|
MOZ_ASSERT(mLockCount >= 0, "VolatileBuffer unlocked too many times!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
VolatileBuffer::VolatileBuffer()
|
VolatileBuffer::VolatileBuffer()
|
||||||
: mBuf(nullptr)
|
: mMutex("VolatileBuffer")
|
||||||
|
, mBuf(nullptr)
|
||||||
, mSize(0)
|
, mSize(0)
|
||||||
, mLockCount(0)
|
, mLockCount(0)
|
||||||
, mHeap(false)
|
, mHeap(false)
|
||||||
|
|
@ -53,6 +54,8 @@ heap_alloc:
|
||||||
|
|
||||||
VolatileBuffer::~VolatileBuffer()
|
VolatileBuffer::~VolatileBuffer()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mLockCount == 0, "Being destroyed with non-zero lock count?");
|
||||||
|
|
||||||
if (OnHeap()) {
|
if (OnHeap()) {
|
||||||
free(mBuf);
|
free(mBuf);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -63,6 +66,8 @@ VolatileBuffer::~VolatileBuffer()
|
||||||
bool
|
bool
|
||||||
VolatileBuffer::Lock(void** aBuf)
|
VolatileBuffer::Lock(void** aBuf)
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
|
MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
|
||||||
|
|
||||||
*aBuf = mBuf;
|
*aBuf = mBuf;
|
||||||
|
|
@ -82,6 +87,8 @@ VolatileBuffer::Lock(void** aBuf)
|
||||||
void
|
void
|
||||||
VolatileBuffer::Unlock()
|
VolatileBuffer::Unlock()
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
|
MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
|
||||||
if (--mLockCount || OnHeap()) {
|
if (--mLockCount || OnHeap()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ extern "C" int posix_memalign(void** memptr, size_t alignment, size_t size);
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
VolatileBuffer::VolatileBuffer()
|
VolatileBuffer::VolatileBuffer()
|
||||||
: mBuf(nullptr)
|
: mMutex("VolatileBuffer")
|
||||||
|
, mBuf(nullptr)
|
||||||
, mSize(0)
|
, mSize(0)
|
||||||
, mLockCount(0)
|
, mLockCount(0)
|
||||||
, mHeap(false)
|
, mHeap(false)
|
||||||
|
|
@ -68,6 +69,8 @@ heap_alloc:
|
||||||
|
|
||||||
VolatileBuffer::~VolatileBuffer()
|
VolatileBuffer::~VolatileBuffer()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mLockCount == 0, "Being destroyed with non-zero lock count?");
|
||||||
|
|
||||||
if (OnHeap()) {
|
if (OnHeap()) {
|
||||||
#ifdef MOZ_MEMORY
|
#ifdef MOZ_MEMORY
|
||||||
free(mBuf);
|
free(mBuf);
|
||||||
|
|
@ -82,6 +85,8 @@ VolatileBuffer::~VolatileBuffer()
|
||||||
bool
|
bool
|
||||||
VolatileBuffer::Lock(void** aBuf)
|
VolatileBuffer::Lock(void** aBuf)
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
|
MOZ_ASSERT(mBuf, "Attempting to lock an uninitialized VolatileBuffer");
|
||||||
|
|
||||||
*aBuf = mBuf;
|
*aBuf = mBuf;
|
||||||
|
|
@ -107,6 +112,8 @@ VolatileBuffer::Lock(void** aBuf)
|
||||||
void
|
void
|
||||||
VolatileBuffer::Unlock()
|
VolatileBuffer::Unlock()
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
|
MOZ_ASSERT(mLockCount > 0, "VolatileBuffer unlocked too many times!");
|
||||||
if (--mLockCount || OnHeap()) {
|
if (--mLockCount || OnHeap()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue