WPILibC++ 2025.0.0-alpha-1-14-g3b6f38d
IndexedClassedHandleResource.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <stdint.h>
8
9#include <array>
10#include <memory>
11#include <vector>
12
13#include <wpi/mutex.h>
14
15#include "hal/Errors.h"
16#include "hal/Types.h"
18
19namespace hal {
20
21/**
22 * The IndexedClassedHandleResource class is a way to track handles. This
23 * version
24 * allows a limited number of handles that are allocated by index.
25 * Because they are allocated by index, each individual index holds its own
26 * mutex, which reduces contention heavily.]
27 *
28 * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
29 * @tparam TStruct The struct type held by this resource
30 * @tparam size The number of resources allowed to be allocated
31 * @tparam enumValue The type value stored in the handle
32 *
33 */
34template <typename THandle, typename TStruct, int16_t size,
35 HAL_HandleEnum enumValue>
38
39 public:
43 delete;
44
45 THandle Allocate(int16_t index, std::shared_ptr<TStruct> toSet,
46 int32_t* status);
47 int16_t GetIndex(THandle handle) {
48 return getHandleTypedIndex(handle, enumValue, m_version);
49 }
50 std::shared_ptr<TStruct> Get(THandle handle);
51 void Free(THandle handle);
52 void ResetHandles() override;
53
54 private:
55 std::array<std::shared_ptr<TStruct>, size> m_structures;
56 std::array<wpi::mutex, size> m_handleMutexes;
57};
58
59template <typename THandle, typename TStruct, int16_t size,
60 HAL_HandleEnum enumValue>
61THandle
63 int16_t index, std::shared_ptr<TStruct> toSet, int32_t* status) {
64 // don't acquire the lock if we can fail early.
65 if (index < 0 || index >= size) {
66 *status = RESOURCE_OUT_OF_RANGE;
67 return HAL_kInvalidHandle;
68 }
69 std::scoped_lock lock(m_handleMutexes[index]);
70 // check for allocation, otherwise allocate and return a valid handle
71 if (m_structures[index] != nullptr) {
72 *status = RESOURCE_IS_ALLOCATED;
73 return HAL_kInvalidHandle;
74 }
75 m_structures[index] = toSet;
76 return static_cast<THandle>(hal::createHandle(index, enumValue, m_version));
77}
78
79template <typename THandle, typename TStruct, int16_t size,
80 HAL_HandleEnum enumValue>
81std::shared_ptr<TStruct>
83 THandle handle) {
84 // get handle index, and fail early if index out of range or wrong handle
85 int16_t index = GetIndex(handle);
86 if (index < 0 || index >= size) {
87 return nullptr;
88 }
89 std::scoped_lock lock(m_handleMutexes[index]);
90 // return structure. Null will propagate correctly, so no need to manually
91 // check.
92 return m_structures[index];
93}
94
95template <typename THandle, typename TStruct, int16_t size,
96 HAL_HandleEnum enumValue>
98 THandle handle) {
99 // get handle index, and fail early if index out of range or wrong handle
100 int16_t index = GetIndex(handle);
101 if (index < 0 || index >= size) {
102 return;
103 }
104 // lock and deallocated handle
105 std::scoped_lock lock(m_handleMutexes[index]);
106 m_structures[index].reset();
107}
108
109template <typename THandle, typename TStruct, int16_t size,
110 HAL_HandleEnum enumValue>
111void IndexedClassedHandleResource<THandle, TStruct, size,
112 enumValue>::ResetHandles() {
113 for (int i = 0; i < size; i++) {
114 std::scoped_lock lock(m_handleMutexes[i]);
115 m_structures[i].reset();
116 }
118}
119} // namespace hal
Base for all HAL Handles.
Definition: HandlesInternal.h:28
virtual void ResetHandles()
int16_t m_version
Definition: HandlesInternal.h:38
The IndexedClassedHandleResource class is a way to track handles.
Definition: IndexedClassedHandleResource.h:36
std::shared_ptr< TStruct > Get(THandle handle)
Definition: IndexedClassedHandleResource.h:82
int16_t GetIndex(THandle handle)
Definition: IndexedClassedHandleResource.h:47
IndexedClassedHandleResource & operator=(const IndexedClassedHandleResource &)=delete
THandle Allocate(int16_t index, std::shared_ptr< TStruct > toSet, int32_t *status)
Definition: IndexedClassedHandleResource.h:62
friend class IndexedClassedHandleResourceTest
Definition: IndexedClassedHandleResource.h:37
void ResetHandles() override
Definition: IndexedClassedHandleResource.h:112
IndexedClassedHandleResource(const IndexedClassedHandleResource &)=delete
void Free(THandle handle)
Definition: IndexedClassedHandleResource.h:97
#define RESOURCE_OUT_OF_RANGE
Definition: Errors.h:80
#define RESOURCE_IS_ALLOCATED
Definition: Errors.h:78
#define HAL_kInvalidHandle
Definition: Types.h:15
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition: InterruptManager.h:13
HAL_HandleEnum
Enum of HAL handle types.
Definition: HandlesInternal.h:46
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, int16_t version)
Create a handle for a specific index, type and version.
int16_t getHandleTypedIndex(HAL_Handle handle, HAL_HandleEnum enumType, int16_t version)
Get if the handle is a correct type and version.
Definition: HandlesInternal.h:134