• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_UTIL_SYSTEM_CALLBACK_ALLOCATOR_H_
18 #define CHRE_UTIL_SYSTEM_CALLBACK_ALLOCATOR_H_
19 
20 #include <cstddef>
21 #include <optional>
22 
23 #include "chre/platform/mutex.h"
24 
25 #include "pw_allocator/allocator.h"
26 #include "pw_allocator/capability.h"
27 #include "pw_allocator/unique_ptr.h"
28 #include "pw_containers/vector.h"
29 #include "pw_function/function.h"
30 
31 namespace chre {
32 
33 //! An allocator that keeps track of callbacks.
34 //! The allocator will call the callback when the underlying type is
35 //! deallocated.
36 //! @param Metadata The metadata type for the callback function
37 template <typename Metadata>
38 class CallbackAllocator : public pw::Allocator {
39  public:
40   static constexpr Capabilities kCapabilities = 0;
41 
42   //! The callback called when the underlying type is deallocated
43   using Callback = pw::Function<void(std::byte *message, size_t length,
44                                      Metadata &&metadata)>;
45 
46   //! A record of a message and its callback
47   struct CallbackRecord {
48     std::byte *message;
49     Metadata metadata;
50     size_t messageSize;
51   };
52 
53   CallbackAllocator(Callback &&callback,
54                     pw::Vector<CallbackRecord> &CallbackRecords,
55                     bool doEraseRecord = true);
56 
57   //! @see pw::Allocator::DoAllocate
58   virtual void *DoAllocate(Layout /* layout */) override;
59 
60   //! @see pw::Allocator::DoDeallocate
61   virtual void DoDeallocate(void *ptr) override;
62 
63   //! Creates a pw::UniquePtr with a callback.
64   //! The callback will be called when the underlying type is deallocated.
65   //! @return A pw::UniquePtr containing data at ptr.
66   [[nodiscard]] pw::UniquePtr<std::byte[]> MakeUniqueArrayWithCallback(
67       std::byte *ptr, size_t size, Metadata &&metadata);
68 
69   //! Gets the callback record for a message. Also removes the record from
70   //! the vector.
71   //! @param ptr The message pointer
72   //! @return The callback record for the message, or std::nullopt if not
73   //! found
74   std::optional<CallbackRecord> GetAndRemoveCallbackRecord(void *ptr);
75 
76  private:
77   //! The callback called on deallocation
78   Callback mCallback;
79 
80   //! The mutex to protect mCallbackRecords
81   Mutex mMutex;
82 
83   //! The list of callback records
84   pw::Vector<CallbackRecord> &mCallbackRecords;
85 
86   //! Whether to erase the record from the vector after the data is freed
87   const bool mDoEraseRecord;
88 };
89 
90 }  // namespace chre
91 
92 #include "chre/util/system/callback_allocator_impl.h"
93 
94 #endif  // CHRE_UTIL_SYSTEM_CALLBACK_ALLOCATOR_H_
95