WPILibC++  unspecified
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
UnlimitedHandleResource.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2008-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/Types.h"
16 #include "HAL/cpp/priority_mutex.h"
17 #include "HAL/handles/HandlesInternal.h"
18 
19 namespace hal {
20 
35 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
37  friend class UnlimitedHandleResourceTest;
38 
39  public:
40  UnlimitedHandleResource() = default;
42  UnlimitedHandleResource& operator=(const UnlimitedHandleResource&) = delete;
43 
44  THandle Allocate(std::shared_ptr<TStruct> structure);
45  std::shared_ptr<TStruct> Get(THandle handle);
46  void Free(THandle handle);
47  void ResetHandles() override;
48 
49  private:
50  std::vector<std::shared_ptr<TStruct>> m_structures;
51  hal::priority_mutex m_handleMutex;
52 };
53 
54 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
56  std::shared_ptr<TStruct> structure) {
57  std::lock_guard<hal::priority_mutex> sync(m_handleMutex);
58  size_t i;
59  for (i = 0; i < m_structures.size(); i++) {
60  if (m_structures[i] == nullptr) {
61  m_structures[i] = structure;
62  return static_cast<THandle>(createHandle(i, enumValue, m_version));
63  }
64  }
65  if (i >= INT16_MAX) return HAL_kInvalidHandle;
66 
67  m_structures.push_back(structure);
68  return static_cast<THandle>(
69  createHandle(static_cast<int16_t>(i), enumValue, m_version));
70 }
71 
72 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
73 std::shared_ptr<TStruct>
74 UnlimitedHandleResource<THandle, TStruct, enumValue>::Get(THandle handle) {
75  int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
76  std::lock_guard<hal::priority_mutex> sync(m_handleMutex);
77  if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
78  return nullptr;
79  return m_structures[index];
80 }
81 
82 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
83 void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
84  THandle handle) {
85  int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
86  std::lock_guard<hal::priority_mutex> sync(m_handleMutex);
87  if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) return;
88  m_structures[index].reset();
89 }
90 
91 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
92 void UnlimitedHandleResource<THandle, TStruct, enumValue>::ResetHandles() {
93  {
94  std::lock_guard<hal::priority_mutex> lock(m_handleMutex);
95  for (size_t i = 0; i < m_structures.size(); i++) {
96  m_structures[i].reset();
97  }
98  }
99  HandleBase::ResetHandles();
100 }
101 } // namespace hal
The UnlimitedHandleResource class is a way to track handles.
Definition: UnlimitedHandleResource.h:36
Definition: HandlesInternal.h:26
Definition: priority_mutex.h:57