Bug 1020090 - Ensure we don't report leaking the GMP free list. r=jesup

This commit is contained in:
Chris Pearce 2014-07-11 15:35:28 +12:00
parent 74e9a36353
commit 6699a6e910
2 changed files with 49 additions and 21 deletions

View File

@ -6,6 +6,8 @@
#include "GMPSharedMemManager.h" #include "GMPSharedMemManager.h"
#include "GMPMessageUtils.h" #include "GMPMessageUtils.h"
#include "mozilla/ipc/SharedMemory.h" #include "mozilla/ipc/SharedMemory.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/ClearOnShutdown.h"
namespace mozilla { namespace mozilla {
namespace gmp { namespace gmp {
@ -17,7 +19,36 @@ namespace gmp {
// Compressed (encoded) data goes from the Decoder parent to the child; // Compressed (encoded) data goes from the Decoder parent to the child;
// pool there, and then return with Encoded() frames and goes into the parent // pool there, and then return with Encoded() frames and goes into the parent
// pool. // pool.
static nsTArray<ipc::Shmem> sGmpFreelist[GMPSharedMemManager::kGMPNumTypes]; static StaticAutoPtr<nsTArray<ipc::Shmem>> sGmpFreelist[GMPSharedMemManager::kGMPNumTypes];
static uint32_t sGMPShmemManagerCount = 0;
GMPSharedMemManager::GMPSharedMemManager()
{
if (!sGMPShmemManagerCount) {
for (uint32_t i = 0; i < GMPSharedMemManager::kGMPNumTypes; i++) {
sGmpFreelist[i] = new nsTArray<ipc::Shmem>();
}
}
sGMPShmemManagerCount++;
}
GMPSharedMemManager::~GMPSharedMemManager()
{
MOZ_ASSERT(sGMPShmemManagerCount > 0);
sGMPShmemManagerCount--;
if (!sGMPShmemManagerCount) {
for (uint32_t i = 0; i < GMPSharedMemManager::kGMPNumTypes; i++) {
sGmpFreelist[i] = nullptr;
}
}
}
static nsTArray<ipc::Shmem>&
GetGmpFreelist(GMPSharedMemManager::GMPMemoryClasses aTypes)
{
return *(sGmpFreelist[aTypes]);
}
static uint32_t sGmpAllocated[GMPSharedMemManager::kGMPNumTypes]; // 0's static uint32_t sGmpAllocated[GMPSharedMemManager::kGMPNumTypes]; // 0's
bool bool
@ -28,11 +59,11 @@ GMPSharedMemManager::MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize,
CheckThread(); CheckThread();
// first look to see if we have a free buffer large enough // first look to see if we have a free buffer large enough
for (uint32_t i = 0; i < sGmpFreelist[aClass].Length(); i++) { for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
MOZ_ASSERT(sGmpFreelist[aClass][i].IsWritable()); MOZ_ASSERT(GetGmpFreelist(aClass)[i].IsWritable());
if (aSize <= sGmpFreelist[aClass][i].Size<uint8_t>()) { if (aSize <= GetGmpFreelist(aClass)[i].Size<uint8_t>()) {
*aMem = sGmpFreelist[aClass][i]; *aMem = GetGmpFreelist(aClass)[i];
sGmpFreelist[aClass].RemoveElementAt(i); GetGmpFreelist(aClass).RemoveElementAt(i);
return true; return true;
} }
} }
@ -56,21 +87,21 @@ GMPSharedMemManager::MgrDeallocShmem(GMPMemoryClasses aClass, ipc::Shmem& aMem)
size_t total = 0; size_t total = 0;
// XXX This works; there are better pool algorithms. We need to avoid // XXX This works; there are better pool algorithms. We need to avoid
// "falling off a cliff" with too low a number // "falling off a cliff" with too low a number
if (sGmpFreelist[aClass].Length() > 10) { if (GetGmpFreelist(aClass).Length() > 10) {
Dealloc(sGmpFreelist[aClass][0]); Dealloc(GetGmpFreelist(aClass)[0]);
sGmpFreelist[aClass].RemoveElementAt(0); GetGmpFreelist(aClass).RemoveElementAt(0);
// The allocation numbers will be fubar on the Child! // The allocation numbers will be fubar on the Child!
sGmpAllocated[aClass]--; sGmpAllocated[aClass]--;
} }
for (uint32_t i = 0; i < sGmpFreelist[aClass].Length(); i++) { for (uint32_t i = 0; i < GetGmpFreelist(aClass).Length(); i++) {
MOZ_ASSERT(sGmpFreelist[aClass][i].IsWritable()); MOZ_ASSERT(GetGmpFreelist(aClass)[i].IsWritable());
total += sGmpFreelist[aClass][i].Size<uint8_t>(); total += GetGmpFreelist(aClass)[i].Size<uint8_t>();
if (size < sGmpFreelist[aClass][i].Size<uint8_t>()) { if (size < GetGmpFreelist(aClass)[i].Size<uint8_t>()) {
sGmpFreelist[aClass].InsertElementAt(i, aMem); GetGmpFreelist(aClass).InsertElementAt(i, aMem);
return true; return true;
} }
} }
sGmpFreelist[aClass].AppendElement(aMem); GetGmpFreelist(aClass).AppendElement(aMem);
return true; return true;
} }
@ -78,7 +109,7 @@ GMPSharedMemManager::MgrDeallocShmem(GMPMemoryClasses aClass, ipc::Shmem& aMem)
uint32_t uint32_t
GMPSharedMemManager::NumInUse(GMPMemoryClasses aClass) GMPSharedMemManager::NumInUse(GMPMemoryClasses aClass)
{ {
return sGmpAllocated[aClass] - sGmpFreelist[aClass].Length(); return sGmpAllocated[aClass] - GetGmpFreelist(aClass).Length();
} }
} }

View File

@ -28,11 +28,8 @@ public:
// (perhaps temporarily). // (perhaps temporarily).
static const uint32_t kGMPBufLimit = 20; static const uint32_t kGMPBufLimit = 20;
GMPSharedMemManager() {} GMPSharedMemManager();
virtual ~GMPSharedMemManager();
virtual ~GMPSharedMemManager() {
// XXX free everything in the freelist
}
virtual bool MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize, virtual bool MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize,
ipc::Shmem::SharedMemory::SharedMemoryType aType, ipc::Shmem::SharedMemory::SharedMemoryType aType,