// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_MEMORY_UNSAFE_SHARED_MEMORY_POOL_H_ #define BASE_MEMORY_UNSAFE_SHARED_MEMORY_POOL_H_ #include #include #include #include "base/base_export.h" #include "base/memory/ref_counted.h" #include "base/memory/unsafe_shared_memory_region.h" #include "base/synchronization/lock.h" #include "base/types/pass_key.h" namespace base { // UnsafeSharedMemoryPool manages allocation and pooling of // UnsafeSharedMemoryRegions. Using pool saves cost of repeated shared memory // allocations. Up-to 32 regions would be pooled. It is thread-safe. May return // bigger regions than requested. If a requested size is increased, all stored // regions are purged. Regions are returned to the buffer on destruction of // |SharedMemoryHandle| if they are of a correct size. class BASE_EXPORT UnsafeSharedMemoryPool : public RefCountedThreadSafe { public: // Used to store the allocation result. // This class returns memory to the pool upon destruction. class BASE_EXPORT Handle { public: Handle(PassKey, UnsafeSharedMemoryRegion region, WritableSharedMemoryMapping mapping, scoped_refptr pool); ~Handle(); // Disallow copy and assign. Handle(const Handle&) = delete; Handle& operator=(const Handle&) = delete; const UnsafeSharedMemoryRegion& GetRegion() const; const WritableSharedMemoryMapping& GetMapping() const; private: UnsafeSharedMemoryRegion region_; WritableSharedMemoryMapping mapping_; scoped_refptr pool_; }; UnsafeSharedMemoryPool(); // Disallow copy and assign. UnsafeSharedMemoryPool(const UnsafeSharedMemoryPool&) = delete; UnsafeSharedMemoryPool& operator=(const UnsafeSharedMemoryPool&) = delete; // Allocates a region of the given |size| or reuses a previous allocation if // possible. std::unique_ptr MaybeAllocateBuffer(size_t size); // Shuts down the pool, freeing all currently unused allocations and freeing // outstanding ones as they are returned. void Shutdown(); private: friend class RefCountedThreadSafe; ~UnsafeSharedMemoryPool(); void ReleaseBuffer(UnsafeSharedMemoryRegion region, WritableSharedMemoryMapping mapping); Lock lock_; // All shared memory regions cached internally are guaranteed to be // at least `region_size_` bytes in size. size_t region_size_ GUARDED_BY(lock_) = 0u; // Cached unused regions and their mappings. std::vector> regions_ GUARDED_BY(lock_); bool is_shutdown_ GUARDED_BY(lock_) = false; }; } // namespace base #endif // BASE_MEMORY_UNSAFE_SHARED_MEMORY_POOL_H_