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