WPILibC++  unspecified
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
IndexedClassedHandleResource.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2016-2017. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #pragma once
9 
10 #include <stdint.h>
11 
12 #include <memory>
13 #include <vector>
14 
15 #include "HAL/Errors.h"
16 #include "HAL/Types.h"
17 #include "HAL/cpp/make_unique.h"
18 #include "HAL/cpp/priority_mutex.h"
19 #include "HAL/handles/HandlesInternal.h"
20 
21 namespace hal {
22 
36 template <typename THandle, typename TStruct, int16_t size,
37  HAL_HandleEnum enumValue>
39  friend class IndexedClassedHandleResourceTest;
40 
41  public:
45  delete;
46 
47  THandle Allocate(int16_t index, std::shared_ptr<TStruct> toSet,
48  int32_t* status);
49  std::shared_ptr<TStruct> Get(THandle handle);
50  void Free(THandle handle);
51 
52  private:
53  std::array<std::shared_ptr<TStruct>[], size> m_structures;
54  std::array<hal::priority_mutex[], size> m_handleMutexes;
55 };
56 
57 template <typename THandle, typename TStruct, int16_t size,
58  HAL_HandleEnum enumValue>
59 IndexedClassedHandleResource<THandle, TStruct, size,
60  enumValue>::IndexedClassedHandleResource() {
61  m_structures = std::make_unique<std::shared_ptr<TStruct>[]>(size);
62  m_handleMutexes = std::make_unique<hal::priority_mutex[]>(size);
63 }
64 
65 template <typename THandle, typename TStruct, int16_t size,
66  HAL_HandleEnum enumValue>
67 THandle
68 IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Allocate(
69  int16_t index, std::shared_ptr<TStruct> toSet, int32_t* status) {
70  // don't aquire the lock if we can fail early.
71  if (index < 0 || index >= size) {
72  *status = RESOURCE_OUT_OF_RANGE;
73  return HAL_kInvalidHandle;
74  }
75  std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
76  // check for allocation, otherwise allocate and return a valid handle
77  if (m_structures[index] != nullptr) {
78  *status = RESOURCE_IS_ALLOCATED;
79  return HAL_kInvalidHandle;
80  }
81  m_structures[index] = toSet;
82  return static_cast<THandle>(hal::createHandle(index, enumValue, m_version));
83 }
84 
85 template <typename THandle, typename TStruct, int16_t size,
86  HAL_HandleEnum enumValue>
87 std::shared_ptr<TStruct> IndexedClassedHandleResource<
88  THandle, TStruct, size, enumValue>::Get(THandle handle) {
89  // get handle index, and fail early if index out of range or wrong handle
90  int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
91  if (index < 0 || index >= size) {
92  return nullptr;
93  }
94  std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
95  // return structure. Null will propogate correctly, so no need to manually
96  // check.
97  return m_structures[index];
98 }
99 
100 template <typename THandle, typename TStruct, int16_t size,
101  HAL_HandleEnum enumValue>
102 void IndexedClassedHandleResource<THandle, TStruct, size, enumValue>::Free(
103  THandle handle) {
104  // get handle index, and fail early if index out of range or wrong handle
105  int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
106  if (index < 0 || index >= size) return;
107  // lock and deallocated handle
108  std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[index]);
109  m_structures[index].reset();
110 }
111 
112 template <typename THandle, typename TStruct, int16_t size,
113  HAL_HandleEnum enumValue>
114 void IndexedClassedHandleResource<THandle, TStruct, size,
115  enumValue>::ResetHandles() {
116  for (int i = 0; i < size; i++) {
117  std::lock_guard<hal::priority_mutex> sync(m_handleMutexes[i]);
118  m_structures[i].reset();
119  }
120  HandleBase::ResetHandles();
121 }
122 } // namespace hal
Definition: HandlesInternal.h:26
The IndexedClassedHandleResource class is a way to track handles.
Definition: IndexedClassedHandleResource.h:38