WPILibC++  unspecified
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
LimitedClassedHandleResource.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 <array>
13 #include <memory>
14 
15 #include "HAL/Types.h"
16 #include "HAL/cpp/make_unique.h"
17 #include "HAL/cpp/priority_mutex.h"
18 #include "HAL/handles/HandlesInternal.h"
19 
20 namespace hal {
21 
33 template <typename THandle, typename TStruct, int16_t size,
34  HAL_HandleEnum enumValue>
36  friend class LimitedClassedHandleResourceTest;
37 
38  public:
39  LimitedClassedHandleResource() = default;
42  delete;
43 
44  THandle Allocate(std::shared_ptr<TStruct> toSet);
45  std::shared_ptr<TStruct> Get(THandle handle);
46  void Free(THandle handle);
47 
48  private:
49  std::array<std::shared_ptr<TStruct>, size> m_structures;
50  std::array<priority_mutex, size> m_handleMutexes;
51  priority_mutex m_allocateMutex;
52 };
53 
54 template <typename THandle, typename TStruct, int16_t size,
55  HAL_HandleEnum enumValue>
56 THandle
58  std::shared_ptr<TStruct> toSet) {
59  // globally lock to loop through indices
60  std::lock_guard<priority_mutex> sync(m_allocateMutex);
61  for (int16_t i = 0; i < size; i++) {
62  if (m_structures[i] == nullptr) {
63  // if a false index is found, grab its specific mutex
64  // and allocate it.
65  std::lock_guard<priority_mutex> sync(m_handleMutexes[i]);
66  m_structures[i] = toSet;
67  return static_cast<THandle>(createHandle(i, enumValue));
68  }
69  }
70  return HAL_kInvalidHandle;
71 }
72 
73 template <typename THandle, typename TStruct, int16_t size,
74  HAL_HandleEnum enumValue>
75 std::shared_ptr<TStruct> LimitedClassedHandleResource<
76  THandle, TStruct, size, enumValue>::Get(THandle handle) {
77  // get handle index, and fail early if index out of range or wrong handle
78  int16_t index = getHandleTypedIndex(handle, enumValue);
79  if (index < 0 || index >= size) {
80  return nullptr;
81  }
82  std::lock_guard<priority_mutex> sync(m_handleMutexes[index]);
83  // return structure. Null will propogate correctly, so no need to manually
84  // check.
85  return m_structures[index];
86 }
87 
88 template <typename THandle, typename TStruct, int16_t size,
89  HAL_HandleEnum enumValue>
90 void LimitedClassedHandleResource<THandle, TStruct, size, enumValue>::Free(
91  THandle handle) {
92  // get handle index, and fail early if index out of range or wrong handle
93  int16_t index = getHandleTypedIndex(handle, enumValue);
94  if (index < 0 || index >= size) return;
95  // lock and deallocated handle
96  std::lock_guard<priority_mutex> sync(m_allocateMutex);
97  std::lock_guard<priority_mutex> lock(m_handleMutexes[index]);
98  m_structures[index].reset();
99 }
100 } // namespace hal
Definition: priority_mutex.h:53
The LimitedClassedHandleResource class is a way to track handles.
Definition: LimitedClassedHandleResource.h:35