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