WPILibC++ 2024.3.2
LimitedClassedHandleResource.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
12#include <wpi/mutex.h>
13
14#include "hal/Types.h"
16
17namespace hal {
18
19/**
20 * The LimitedClassedHandleResource class is a way to track handles. This
21 * version
22 * allows a limited number of handles that are allocated sequentially.
23 *
24 * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
25 * @tparam TStruct The struct type held by this resource
26 * @tparam size The number of resources allowed to be allocated
27 * @tparam enumValue The type value stored in the handle
28 *
29 */
30template <typename THandle, typename TStruct, int16_t size,
31 HAL_HandleEnum enumValue>
34
35 public:
39 delete;
40
41 THandle Allocate(std::shared_ptr<TStruct> toSet);
42 int16_t GetIndex(THandle handle) {
43 return getHandleTypedIndex(handle, enumValue, m_version);
44 }
45 std::shared_ptr<TStruct> Get(THandle handle);
46 void Free(THandle handle);
47 void ResetHandles() override;
48
49 private:
50 std::array<std::shared_ptr<TStruct>, size> m_structures;
51 std::array<wpi::mutex, size> m_handleMutexes;
52 wpi::mutex m_allocateMutex;
53};
54
55template <typename THandle, typename TStruct, int16_t size,
56 HAL_HandleEnum enumValue>
57THandle
59 std::shared_ptr<TStruct> toSet) {
60 // globally lock to loop through indices
61 std::scoped_lock lock(m_allocateMutex);
62 for (int16_t i = 0; i < size; i++) {
63 if (m_structures[i] == nullptr) {
64 // if a false index is found, grab its specific mutex
65 // and allocate it.
66 std::scoped_lock lock(m_handleMutexes[i]);
67 m_structures[i] = toSet;
68 return static_cast<THandle>(createHandle(i, enumValue, m_version));
69 }
70 }
71 return HAL_kInvalidHandle;
72}
73
74template <typename THandle, typename TStruct, int16_t size,
75 HAL_HandleEnum enumValue>
76std::shared_ptr<TStruct>
78 THandle handle) {
79 // get handle index, and fail early if index out of range or wrong handle
80 int16_t index = GetIndex(handle);
81 if (index < 0 || index >= size) {
82 return nullptr;
83 }
84 std::scoped_lock lock(m_handleMutexes[index]);
85 // return structure. Null will propagate correctly, so no need to manually
86 // check.
87 return m_structures[index];
88}
89
90template <typename THandle, typename TStruct, int16_t size,
91 HAL_HandleEnum enumValue>
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;
98 }
99 // lock and deallocated handle
100 std::scoped_lock allocateLock(m_allocateMutex);
101 std::scoped_lock handleLock(m_handleMutexes[index]);
102 m_structures[index].reset();
103}
104
105template <typename THandle, typename TStruct, int16_t size,
106 HAL_HandleEnum enumValue>
107void LimitedClassedHandleResource<THandle, TStruct, size,
108 enumValue>::ResetHandles() {
109 {
110 std::scoped_lock allocateLock(m_allocateMutex);
111 for (int i = 0; i < size; i++) {
112 std::scoped_lock handleLock(m_handleMutexes[i]);
113 m_structures[i].reset();
114 }
115 }
117}
118} // namespace hal
Base for all HAL Handles.
Definition: HandlesInternal.h:28
virtual void ResetHandles()
int16_t m_version
Definition: HandlesInternal.h:38
The LimitedClassedHandleResource class is a way to track handles.
Definition: LimitedClassedHandleResource.h:32
void ResetHandles() override
Definition: LimitedClassedHandleResource.h:108
THandle Allocate(std::shared_ptr< TStruct > toSet)
Definition: LimitedClassedHandleResource.h:58
int16_t GetIndex(THandle handle)
Definition: LimitedClassedHandleResource.h:42
LimitedClassedHandleResource(const LimitedClassedHandleResource &)=delete
void Free(THandle handle)
Definition: LimitedClassedHandleResource.h:92
std::shared_ptr< TStruct > Get(THandle handle)
Definition: LimitedClassedHandleResource.h:77
friend class LimitedClassedHandleResourceTest
Definition: LimitedClassedHandleResource.h:33
LimitedClassedHandleResource & operator=(const LimitedClassedHandleResource &)=delete
#define HAL_kInvalidHandle
Definition: Types.h:15
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition: ChipObject.h:40
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
::std::mutex mutex
Definition: mutex.h:17