WPILibC++  2018.4.1-20180729133221-1141-g00c2cd7
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
LimitedHandleResource.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2016-2018 FIRST. 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 <wpi/mutex.h>
16 
17 #include "HandlesInternal.h"
18 #include "hal/Types.h"
19 
20 namespace hal {
21 
32 template <typename THandle, typename TStruct, int16_t size,
33  HAL_HandleEnum enumValue>
35  friend class LimitedHandleResourceTest;
36 
37  public:
38  LimitedHandleResource() = default;
40  LimitedHandleResource& operator=(const LimitedHandleResource&) = delete;
41 
42  THandle Allocate();
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 
53 template <typename THandle, typename TStruct, int16_t size,
54  HAL_HandleEnum enumValue>
56  // globally lock to loop through indices
57  std::lock_guard<wpi::mutex> 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::lock_guard<wpi::mutex> 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 
70 template <typename THandle, typename TStruct, int16_t size,
71  HAL_HandleEnum enumValue>
72 std::shared_ptr<TStruct>
73 LimitedHandleResource<THandle, TStruct, size, enumValue>::Get(THandle handle) {
74  // get handle index, and fail early if index out of range or wrong handle
75  int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
76  if (index < 0 || index >= size) {
77  return nullptr;
78  }
79  std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
80  // return structure. Null will propogate correctly, so no need to manually
81  // check.
82  return m_structures[index];
83 }
84 
85 template <typename THandle, typename TStruct, int16_t size,
86  HAL_HandleEnum enumValue>
87 void LimitedHandleResource<THandle, TStruct, size, enumValue>::Free(
88  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) return;
92  // lock and deallocated handle
93  std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
94  std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[index]);
95  m_structures[index].reset();
96 }
97 
98 template <typename THandle, typename TStruct, int16_t size,
99  HAL_HandleEnum enumValue>
100 void LimitedHandleResource<THandle, TStruct, size, enumValue>::ResetHandles() {
101  {
102  std::lock_guard<wpi::mutex> allocateLock(m_allocateMutex);
103  for (int i = 0; i < size; i++) {
104  std::lock_guard<wpi::mutex> handleLock(m_handleMutexes[i]);
105  m_structures[i].reset();
106  }
107  }
108  HandleBase::ResetHandles();
109 }
110 } // namespace hal
The LimitedHandleResource class is a way to track handles.
Definition: LimitedHandleResource.h:34
Base for all HAL Handles.
Definition: HandlesInternal.h:29
Definition: NotifyListenerVector.h:18
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:999