• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/compiler_specific.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/unsafe_shared_memory_region.h"
16 #include "base/synchronization/lock.h"
17 #include "base/types/pass_key.h"
18 
19 namespace base {
20 
21 // UnsafeSharedMemoryPool manages allocation and pooling of
22 // UnsafeSharedMemoryRegions. Using pool saves cost of repeated shared memory
23 // allocations. Up-to 32 regions would be pooled. It is thread-safe. May return
24 // bigger regions than requested. If a requested size is increased, all stored
25 // regions are purged. Regions are returned to the buffer on destruction of
26 // |SharedMemoryHandle| if they are of a correct size.
27 class BASE_EXPORT UnsafeSharedMemoryPool
28     : public RefCountedThreadSafe<UnsafeSharedMemoryPool> {
29  public:
30   // Used to store the allocation result.
31   // This class returns memory to the pool upon destruction.
32   class BASE_EXPORT Handle {
33    public:
34     Handle(PassKey<UnsafeSharedMemoryPool>,
35            UnsafeSharedMemoryRegion region,
36            WritableSharedMemoryMapping mapping,
37            scoped_refptr<UnsafeSharedMemoryPool> pool);
38 
39     ~Handle();
40     // Disallow copy and assign.
41     Handle(const Handle&) = delete;
42     Handle& operator=(const Handle&) = delete;
43 
44     const UnsafeSharedMemoryRegion& GetRegion() const LIFETIME_BOUND;
45     const WritableSharedMemoryMapping& GetMapping() const LIFETIME_BOUND;
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