ShmemRecycleAllocator.h (2935B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #ifndef include_dom_media_ipc_ShmemRecycleAllocator_h 7 #define include_dom_media_ipc_ShmemRecycleAllocator_h 8 9 #include "mozilla/ShmemPool.h" 10 11 namespace mozilla { 12 13 // When used with ShmemRecycleAllocator instances, it allows for preventing a 14 // subset of shmems from being recycled until a transaction is complete. This is 15 // useful in cases such as encoding, where an arbitrary number of frames may be 16 // sent for encoding before any others complete. This instead allows us to 17 // recycle shmems as individual transactions complete without waiting for all 18 // outstanding to be complete first. 19 class ShmemRecycleTicket { 20 public: 21 NS_INLINE_DECL_REFCOUNTING_ONEVENTTARGET(ShmemRecycleTicket) 22 23 ShmemRecycleTicket() = default; 24 25 private: 26 template <class T> 27 friend class ShmemRecycleAllocator; 28 29 ~ShmemRecycleTicket() { MOZ_DIAGNOSTIC_ASSERT(mUsedShmems.IsEmpty()); } 30 31 AutoTArray<ShmemBuffer, 4> mUsedShmems; 32 }; 33 34 template <class T> 35 class ShmemRecycleAllocator { 36 public: 37 explicit ShmemRecycleAllocator(T* aActor) 38 : mActor(aActor), mPool(1, ShmemPool::PoolType::DynamicPool) {} 39 ShmemBuffer AllocateBuffer(size_t aSize, 40 ShmemRecycleTicket* aTicket = nullptr, 41 ShmemPool::AllocationPolicy aPolicy = 42 ShmemPool::AllocationPolicy::Unsafe) { 43 ShmemBuffer buffer = mPool.Get(mActor, aSize, aPolicy); 44 if (!buffer.Valid()) { 45 return buffer; 46 } 47 MOZ_DIAGNOSTIC_ASSERT(aSize <= buffer.Get().Size<uint8_t>()); 48 if (aTicket) { 49 aTicket->mUsedShmems.AppendElement(buffer.Get()); 50 } else { 51 mUsedShmems.AppendElement(buffer.Get()); 52 } 53 mNeedCleanup = true; 54 return buffer; 55 } 56 57 void ReleaseBuffer(ShmemBuffer&& aBuffer) { mPool.Put(std::move(aBuffer)); } 58 59 void ReleaseAllBuffers() { 60 for (auto&& mem : mUsedShmems) { 61 ReleaseBuffer(ShmemBuffer(mem.Get())); 62 } 63 mUsedShmems.Clear(); 64 } 65 66 void ReleaseTicket(ShmemRecycleTicket* aTicket) { 67 for (auto&& mem : aTicket->mUsedShmems) { 68 ReleaseBuffer(ShmemBuffer(mem.Get())); 69 } 70 aTicket->mUsedShmems.Clear(); 71 } 72 73 void CleanupShmemRecycleAllocator() { 74 ReleaseAllBuffers(); 75 mPool.Cleanup(mActor); 76 mNeedCleanup = false; 77 } 78 79 ~ShmemRecycleAllocator() { 80 MOZ_DIAGNOSTIC_ASSERT(mUsedShmems.IsEmpty() && !mNeedCleanup, 81 "Shmems not all deallocated"); 82 } 83 84 private: 85 T* const mActor; 86 ShmemPool mPool; 87 AutoTArray<ShmemBuffer, 4> mUsedShmems; 88 bool mNeedCleanup = false; 89 }; 90 91 } // namespace mozilla 92 93 #endif // include_dom_media_ipc_ShmemRecycleAllocator_h