xref: /aosp_15_r20/external/cronet/base/memory/unsafe_shared_memory_pool.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_MEMORY_UNSAFE_SHARED_MEMORY_POOL_H_
6 #define BASE_MEMORY_UNSAFE_SHARED_MEMORY_POOL_H_
7 
8 #include <memory>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/base_export.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/unsafe_shared_memory_region.h"
15 #include "base/synchronization/lock.h"
16 #include "base/types/pass_key.h"
17 
18 namespace base {
19 
20 // UnsafeSharedMemoryPool manages allocation and pooling of
21 // UnsafeSharedMemoryRegions. Using pool saves cost of repeated shared memory
22 // allocations. Up-to 32 regions would be pooled. It is thread-safe. May return
23 // bigger regions than requested. If a requested size is increased, all stored
24 // regions are purged. Regions are returned to the buffer on destruction of
25 // |SharedMemoryHandle| if they are of a correct size.
26 class BASE_EXPORT UnsafeSharedMemoryPool
27     : public RefCountedThreadSafe<UnsafeSharedMemoryPool> {
28  public:
29   // Used to store the allocation result.
30   // This class returns memory to the pool upon destruction.
31   class BASE_EXPORT Handle {
32    public:
33     Handle(PassKey<UnsafeSharedMemoryPool>,
34            UnsafeSharedMemoryRegion region,
35            WritableSharedMemoryMapping mapping,
36            scoped_refptr<UnsafeSharedMemoryPool> pool);
37 
38     ~Handle();
39     // Disallow copy and assign.
40     Handle(const Handle&) = delete;
41     Handle& operator=(const Handle&) = delete;
42 
43     const UnsafeSharedMemoryRegion& GetRegion() const;
44 
45     const WritableSharedMemoryMapping& GetMapping() const;
46 
47    private:
48     UnsafeSharedMemoryRegion region_;
49     WritableSharedMemoryMapping mapping_;
50     scoped_refptr<UnsafeSharedMemoryPool> pool_;
51   };
52 
53   UnsafeSharedMemoryPool();
54   // Disallow copy and assign.
55   UnsafeSharedMemoryPool(const UnsafeSharedMemoryPool&) = delete;
56   UnsafeSharedMemoryPool& operator=(const UnsafeSharedMemoryPool&) = delete;
57 
58   // Allocates a region of the given |size| or reuses a previous allocation if
59   // possible.
60   std::unique_ptr<Handle> MaybeAllocateBuffer(size_t size);
61 
62   // Shuts down the pool, freeing all currently unused allocations and freeing
63   // outstanding ones as they are returned.
64   void Shutdown();
65 
66  private:
67   friend class RefCountedThreadSafe<UnsafeSharedMemoryPool>;
68   ~UnsafeSharedMemoryPool();
69 
70   void ReleaseBuffer(UnsafeSharedMemoryRegion region,
71                      WritableSharedMemoryMapping mapping);
72 
73   Lock lock_;
74   // All shared memory regions cached internally are guaranteed to be
75   // at least `region_size_` bytes in size.
76   size_t region_size_ GUARDED_BY(lock_) = 0u;
77   // Cached unused regions and their mappings.
78   std::vector<std::pair<UnsafeSharedMemoryRegion, WritableSharedMemoryMapping>>
79       regions_ GUARDED_BY(lock_);
80   bool is_shutdown_ GUARDED_BY(lock_) = false;
81 };
82 
83 }  // namespace base
84 
85 #endif  // BASE_MEMORY_UNSAFE_SHARED_MEMORY_POOL_H_
86