xref: /aosp_15_r20/system/libfmq/include/fmq/AidlMessageQueue.h (revision be431cd81a9a2349eaea34eb56fcf6d1608da596)
1 /*
2  * Copyright (C) 2020 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 #pragma once
17 #include <aidl/android/hardware/common/fmq/MQDescriptor.h>
18 #include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h>
19 #include <aidl/android/hardware/common/fmq/UnsynchronizedWrite.h>
20 #include "AidlMQDescriptorShim.h"
21 #include "AidlMessageQueueBase.h"
22 
23 namespace android {
24 using aidl::android::hardware::common::fmq::MQDescriptor;
25 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
26 using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
27 using android::details::AidlMQDescriptorShim;
28 using android::hardware::MQFlavor;
29 
30 template <>
31 struct FlavorTypeToValue<aidl::android::hardware::common::fmq::SynchronizedReadWrite> {
32     static constexpr MQFlavor value = hardware::kSynchronizedReadWrite;
33 };
34 
35 template <>
36 struct FlavorTypeToValue<aidl::android::hardware::common::fmq::UnsynchronizedWrite> {
37     static constexpr MQFlavor value = hardware::kUnsynchronizedWrite;
38 };
39 
40 struct BackendTypesStore {
41     template <typename T, MQFlavor flavor>
42     using AidlMQDescriptorShimType = android::details::AidlMQDescriptorShim<T, flavor>;
43     using GrantorDescriptorType = aidl::android::hardware::common::fmq::GrantorDescriptor;
44     template <typename T, typename flavor>
45     using MQDescriptorType = aidl::android::hardware::common::fmq::MQDescriptor<T, flavor>;
46     using FileDescriptorType = ndk::ScopedFileDescriptor;
47     static FileDescriptorType createFromInt(int fd) { return FileDescriptorType(fd); }
48 };
49 
50 template <typename T, typename U>
51 struct AidlMessageQueue final : public AidlMessageQueueBase<T, U, BackendTypesStore> {
52     AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers = true);
53     ~AidlMessageQueue() = default;
54 
55     /**
56      * This constructor uses Ashmem shared memory to create an FMQ
57      * that can contain a maximum of 'numElementsInQueue' elements of type T.
58      *
59      * @param numElementsInQueue Capacity of the AidlMessageQueue in terms of T.
60      * @param configureEventFlagWord Boolean that specifies if memory should
61      * also be allocated and mapped for an EventFlag word.
62      * @param bufferFd User-supplied file descriptor to map the memory for the ringbuffer
63      * By default, bufferFd=-1 means library will allocate ashmem region for ringbuffer.
64      * MessageQueue takes ownership of the file descriptor.
65      * @param bufferSize size of buffer in bytes that bufferFd represents. This
66      * size must be larger than or equal to (numElementsInQueue * sizeof(T)).
67      * Otherwise, operations will cause out-of-bounds memory access.
68      */
69     AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord,
70                      android::base::unique_fd bufferFd, size_t bufferSize);
71 
72     AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false)
73         : AidlMessageQueue(numElementsInQueue, configureEventFlagWord, android::base::unique_fd(),
74                            0) {}
75 
76     template <typename V = T>
77     AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false,
78                      std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum = sizeof(T))
79         : AidlMessageQueue(numElementsInQueue, configureEventFlagWord, android::base::unique_fd(),
80                            0, quantum) {}
81 
82     template <typename V = T>
83     AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord,
84                      android::base::unique_fd bufferFd, size_t bufferSize,
85                      std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum);
86 };
87 
88 template <typename T, typename U>
89 AidlMessageQueue<T, U>::AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers)
90     : AidlMessageQueueBase<T, U, BackendTypesStore>(desc, resetPointers) {}
91 
92 template <typename T, typename U>
93 AidlMessageQueue<T, U>::AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord,
94                                          android::base::unique_fd bufferFd, size_t bufferSize)
95     : AidlMessageQueueBase<T, U, BackendTypesStore>(numElementsInQueue, configureEventFlagWord,
96                                                     std::move(bufferFd), bufferSize) {}
97 
98 template <typename T, typename U>
99 template <typename V>
100 AidlMessageQueue<T, U>::AidlMessageQueue(
101         size_t numElementsInQueue, bool configureEventFlagWord, android::base::unique_fd bufferFd,
102         size_t bufferSize, std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum)
103     : AidlMessageQueueBase<T, U, BackendTypesStore>(numElementsInQueue, configureEventFlagWord,
104                                                     std::move(bufferFd), bufferSize, quantum) {}
105 
106 }  // namespace android
107