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