WPILibC++ 2027.0.0-alpha-5
Loading...
Searching...
No Matches
IndexedClassedHandleResource.hpp
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
13#include "wpi/hal/Errors.h"
14#include "wpi/hal/Types.h"
16#include "wpi/util/expected"
17#include "wpi/util/mutex.hpp"
18
19namespace wpi::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
46 int16_t index, std::shared_ptr<TStruct> toSet, std::string_view name,
47 int offset = 0);
48 int16_t GetIndex(THandle handle) {
49 return getHandleTypedIndex(handle, enumValue, m_version);
50 }
51 std::shared_ptr<TStruct> Get(THandle handle);
52 void Free(THandle handle);
53 void ResetHandles() override;
54
55 private:
56 std::array<std::shared_ptr<TStruct>, size> m_structures;
57 std::array<wpi::util::mutex, size> m_handleMutexes;
58};
59
60template <typename THandle, typename TStruct, int16_t size,
61 HAL_HandleEnum enumValue>
64 int16_t index, std::shared_ptr<TStruct> toSet, std::string_view name,
65 int offset) {
66 // don't acquire the lock if we can fail early.
67 if (index < 0 || index >= size) {
70 size + offset, index + offset));
71 }
72 std::scoped_lock lock(m_handleMutexes[index]);
73 // check for allocation, otherwise allocate and return a valid handle
74 if (m_structures[index] != nullptr) {
78 m_structures[index]->previousAllocation));
79 } else {
81 HAL_RESOURCE_IS_ALLOCATED, name, index + offset, "unknown"));
82 }
83 }
84 m_structures[index] = toSet;
85 return static_cast<THandle>(
87}
88
89template <typename THandle, typename TStruct, int16_t size,
90 HAL_HandleEnum enumValue>
91std::shared_ptr<TStruct>
93 THandle handle) {
94 // get handle index, and fail early if index out of range or wrong handle
95 int16_t index = GetIndex(handle);
96 if (index < 0 || index >= size) {
97 return nullptr;
98 }
99 std::scoped_lock lock(m_handleMutexes[index]);
100 // return structure. Null will propagate correctly, so no need to manually
101 // check.
102 return m_structures[index];
103}
104
105template <typename THandle, typename TStruct, int16_t size,
106 HAL_HandleEnum enumValue>
108 THandle handle) {
109 // get handle index, and fail early if index out of range or wrong handle
110 int16_t index = GetIndex(handle);
111 if (index < 0 || index >= size) {
112 return;
113 }
114 // lock and deallocated handle
115 std::scoped_lock lock(m_handleMutexes[index]);
116 m_structures[index].reset();
117}
118
119template <typename THandle, typename TStruct, int16_t size,
120 HAL_HandleEnum enumValue>
121void IndexedClassedHandleResource<THandle, TStruct, size,
122 enumValue>::ResetHandles() {
123 for (int i = 0; i < size; i++) {
124 std::scoped_lock lock(m_handleMutexes[i]);
125 m_structures[i].reset();
126 }
128}
129} // namespace wpi::hal
@ index
Definition base.h:690
@ name
Definition base.h:690
virtual void ResetHandles()
int16_t m_version
Definition HandlesInternal.hpp:47
The IndexedClassedHandleResource class is a way to track handles.
Definition IndexedClassedHandleResource.hpp:36
wpi::util::expected< THandle, HAL_Status > Allocate(int16_t index, std::shared_ptr< TStruct > toSet, std::string_view name, int offset=0)
Definition IndexedClassedHandleResource.hpp:63
std::shared_ptr< TStruct > Get(THandle handle)
Definition IndexedClassedHandleResource.hpp:92
friend class IndexedClassedHandleResourceTest
Definition IndexedClassedHandleResource.hpp:37
IndexedClassedHandleResource & operator=(const IndexedClassedHandleResource &)=delete
int16_t GetIndex(THandle handle)
Definition IndexedClassedHandleResource.hpp:48
IndexedClassedHandleResource(const IndexedClassedHandleResource &)=delete
void ResetHandles() override
Definition IndexedClassedHandleResource.hpp:122
void Free(THandle handle)
Definition IndexedClassedHandleResource.hpp:107
An expected<T, E> object is an object that contains the storage for another object and manages the li...
Definition expected:1250
Definition expected:142
Definition HandlesInternal.hpp:29
#define HAL_RESOURCE_IS_ALLOCATED
Definition Errors.h:39
#define HAL_RESOURCE_OUT_OF_RANGE
Definition Errors.h:41
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition Types.hpp:9
HAL_HandleEnum
Enum of HAL handle types.
Definition HandlesInternal.hpp:55
int16_t getHandleTypedIndex(HAL_Handle handle, HAL_HandleEnum enumType, int16_t version)
Get if the handle is a correct type and version.
Definition HandlesInternal.hpp:139
HAL_Status MakeErrorIndexOutOfRange(HAL_Status status, std::string_view message, int32_t minimum, int32_t maximum, int32_t channel)
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, int16_t version)
Create a handle for a specific index, type and version.
HAL_Status MakeErrorPreviouslyAllocated(HAL_Status status, std::string_view message, int32_t channel, std::string_view previousAllocation)