WPILibC++  2019.1.1-beta-1-31-g81d10bc
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
DigitalHandleResource.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 "hal/Errors.h"
18 #include "hal/Types.h"
19 #include "hal/handles/HandlesInternal.h"
20 
21 namespace hal {
22 
35 template <typename THandle, typename TStruct, int16_t size>
37  friend class DigitalHandleResourceTest;
38 
39  public:
40  DigitalHandleResource() = default;
42  DigitalHandleResource& operator=(const DigitalHandleResource&) = delete;
43 
44  THandle Allocate(int16_t index, HAL_HandleEnum enumValue, int32_t* status);
45  std::shared_ptr<TStruct> Get(THandle handle, HAL_HandleEnum enumValue);
46  void Free(THandle handle, HAL_HandleEnum enumValue);
47  void ResetHandles() override;
48 
49  private:
50  std::array<std::shared_ptr<TStruct>, size> m_structures;
51  std::array<wpi::mutex, size> m_handleMutexes;
52 };
53 
54 template <typename THandle, typename TStruct, int16_t size>
56  int16_t index, HAL_HandleEnum enumValue, int32_t* status) {
57  // don't aquire the lock if we can fail early.
58  if (index < 0 || index >= size) {
59  *status = RESOURCE_OUT_OF_RANGE;
60  return HAL_kInvalidHandle;
61  }
62  std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
63  // check for allocation, otherwise allocate and return a valid handle
64  if (m_structures[index] != nullptr) {
65  *status = RESOURCE_IS_ALLOCATED;
66  return HAL_kInvalidHandle;
67  }
68  m_structures[index] = std::make_shared<TStruct>();
69  return static_cast<THandle>(hal::createHandle(index, enumValue, m_version));
70 }
71 
72 template <typename THandle, typename TStruct, int16_t size>
73 std::shared_ptr<TStruct> DigitalHandleResource<THandle, TStruct, size>::Get(
74  THandle handle, HAL_HandleEnum enumValue) {
75  // get handle index, and fail early if index out of range or wrong handle
76  int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
77  if (index < 0 || index >= size) {
78  return nullptr;
79  }
80  std::lock_guard<wpi::mutex> lock(m_handleMutexes[index]);
81  // return structure. Null will propogate correctly, so no need to manually
82  // check.
83  return m_structures[index];
84 }
85 
86 template <typename THandle, typename TStruct, int16_t size>
87 void DigitalHandleResource<THandle, TStruct, size>::Free(
88  THandle handle, HAL_HandleEnum enumValue) {
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> lock(m_handleMutexes[index]);
94  m_structures[index].reset();
95 }
96 
97 template <typename THandle, typename TStruct, int16_t size>
98 void DigitalHandleResource<THandle, TStruct, size>::ResetHandles() {
99  for (int i = 0; i < size; i++) {
100  std::lock_guard<wpi::mutex> lock(m_handleMutexes[i]);
101  m_structures[i].reset();
102  }
103  HandleBase::ResetHandles();
104 }
105 } // namespace hal
HAL_HandleEnum
Enum of HAL handle types.
Definition: HandlesInternal.h:47
Base for all HAL Handles.
Definition: HandlesInternal.h:29
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition: SimDataValue.h:19
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
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, int16_t version)
Create a handle for a specific index, type and version.
The DigitalHandleResource class is a way to track handles.
Definition: DigitalHandleResource.h:36