GMPSharedMemManager.cpp (2466B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "GMPSharedMemManager.h" 7 8 #include "mozilla/ipc/SharedMemoryMapping.h" 9 10 namespace mozilla::gmp { 11 12 GMPSharedMemManager::~GMPSharedMemManager() { 13 #ifdef DEBUG 14 for (const auto& pool : mPool) { 15 MOZ_ASSERT(pool.IsEmpty()); 16 } 17 #endif 18 } 19 20 void GMPSharedMemManager::PurgeSmallerShmem(nsTArray<ipc::Shmem>& aPool, 21 size_t aSize) { 22 aPool.RemoveElementsBy([&](ipc::Shmem& shmem) { 23 if (!shmem.IsWritable()) { 24 MOZ_ASSERT_UNREACHABLE("Shmem must be writable!"); 25 return true; 26 } 27 if (shmem.Size<uint8_t>() >= aSize) { 28 return false; 29 } 30 MgrDeallocShmem(shmem); 31 return true; 32 }); 33 } 34 35 bool GMPSharedMemManager::MgrTakeShmem(GMPSharedMemClass aClass, 36 ipc::Shmem* aMem) { 37 MOZ_ASSERT(MgrIsOnOwningThread()); 38 39 auto& pool = mPool[size_t(aClass)]; 40 if (pool.IsEmpty()) { 41 return false; 42 } 43 44 *aMem = pool.PopLastElement(); 45 return true; 46 } 47 48 bool GMPSharedMemManager::MgrTakeShmem(GMPSharedMemClass aClass, size_t aSize, 49 ipc::Shmem* aMem) { 50 MOZ_ASSERT(MgrIsOnOwningThread()); 51 52 auto& pool = mPool[size_t(aClass)]; 53 size_t alignedSize = ipc::shared_memory::PageAlignedSize(aSize); 54 PurgeSmallerShmem(pool, alignedSize); 55 if (pool.IsEmpty()) { 56 return MgrAllocShmem(alignedSize, aMem); 57 } 58 59 *aMem = pool.PopLastElement(); 60 return true; 61 } 62 63 void GMPSharedMemManager::MgrGiveShmem(GMPSharedMemClass aClass, 64 ipc::Shmem&& aMem) { 65 MOZ_ASSERT(MgrIsOnOwningThread()); 66 67 if (!aMem.IsWritable()) { 68 return; 69 } 70 71 auto& pool = mPool[size_t(aClass)]; 72 PurgeSmallerShmem(pool, aMem.Size<uint8_t>()); 73 74 if (pool.Length() >= kMaxPoolLength) { 75 MgrDeallocShmem(aMem); 76 return; 77 } 78 79 pool.AppendElement(std::move(aMem)); 80 } 81 82 void GMPSharedMemManager::MgrPurgeShmems() { 83 MOZ_ASSERT(MgrIsOnOwningThread()); 84 85 for (auto& pool : mPool) { 86 for (auto& shmem : pool) { 87 if (shmem.IsWritable()) { 88 MgrDeallocShmem(shmem); 89 } else { 90 MOZ_ASSERT_UNREACHABLE("Shmem must be writable!"); 91 } 92 } 93 pool.Clear(); 94 } 95 } 96 97 } // namespace mozilla::gmp