WPILibC++  unspecified
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
DigitalHandleResource.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) FIRST 2016. 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/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 
35 template <typename THandle, typename TStruct, int16_t size>
37  friend class DigitalHandleResourceTest;
38 
39  public:
41  DigitalHandleResource operator=(const DigitalHandleResource&) = delete;
42  DigitalHandleResource() = default;
43  THandle Allocate(int16_t index, HAL_HandleEnum enumValue, int32_t* status);
44  std::shared_ptr<TStruct> Get(THandle handle, HAL_HandleEnum enumValue);
45  void Free(THandle handle, HAL_HandleEnum enumValue);
46 
47  private:
48  std::array<std::shared_ptr<TStruct>, size> m_structures;
49  std::array<priority_mutex, size> m_handleMutexes;
50 };
51 
52 template <typename THandle, typename TStruct, int16_t size>
54  int16_t index, HAL_HandleEnum enumValue, int32_t* status) {
55  // don't aquire the lock if we can fail early.
56  if (index < 0 || index >= size) {
57  *status = RESOURCE_OUT_OF_RANGE;
58  return HAL_kInvalidHandle;
59  }
60  std::lock_guard<priority_mutex> sync(m_handleMutexes[index]);
61  // check for allocation, otherwise allocate and return a valid handle
62  if (m_structures[index] != nullptr) {
63  *status = RESOURCE_IS_ALLOCATED;
64  return HAL_kInvalidHandle;
65  }
66  m_structures[index] = std::make_shared<TStruct>();
67  return static_cast<THandle>(hal::createHandle(index, enumValue));
68 }
69 
70 template <typename THandle, typename TStruct, int16_t size>
71 std::shared_ptr<TStruct> DigitalHandleResource<THandle, TStruct, size>::Get(
72  THandle handle, HAL_HandleEnum enumValue) {
73  // get handle index, and fail early if index out of range or wrong handle
74  int16_t index = getHandleTypedIndex(handle, enumValue);
75  if (index < 0 || index >= size) {
76  return nullptr;
77  }
78  std::lock_guard<priority_mutex> sync(m_handleMutexes[index]);
79  // return structure. Null will propogate correctly, so no need to manually
80  // check.
81  return m_structures[index];
82 }
83 
84 template <typename THandle, typename TStruct, int16_t size>
85 void DigitalHandleResource<THandle, TStruct, size>::Free(
86  THandle handle, HAL_HandleEnum enumValue) {
87  // get handle index, and fail early if index out of range or wrong handle
88  int16_t index = getHandleTypedIndex(handle, enumValue);
89  if (index < 0 || index >= size) return;
90  // lock and deallocated handle
91  std::lock_guard<priority_mutex> sync(m_handleMutexes[index]);
92  m_structures[index].reset();
93 }
94 } // namespace hal
The DigitalHandleResource class is a way to track handles.
Definition: DigitalHandleResource.h:36