RLBox
rlbox_app_pointer.hpp
1 #pragma once
2 // IWYU pragma: private, include "rlbox.hpp"
3 // IWYU pragma: friend "rlbox_.*\.hpp"
4 
5 #include <map>
6 #ifndef RLBOX_USE_CUSTOM_SHARED_LOCK
7 # include <shared_mutex>
8 #endif
9 #include <type_traits>
10 
11 #include "rlbox_helpers.hpp"
12 #include "rlbox_type_traits.hpp"
13 #include "rlbox_types.hpp"
14 
15 namespace rlbox {
16 
17 template<typename T_PointerType>
19 {
20 
21 private:
22  using T_PointerTypeUnsigned = detail::unsigned_int_of_size_t<T_PointerType>;
23 
24  std::map<T_PointerTypeUnsigned, void*> pointer_map;
25  T_PointerTypeUnsigned counter = 1;
26  RLBOX_SHARED_LOCK(map_mutex);
27 
28  T_PointerType get_unused_index()
29  {
30  constexpr auto max_val = std::numeric_limits<T_PointerTypeUnsigned>::max();
31  constexpr auto min_val = std::numeric_limits<T_PointerTypeUnsigned>::min();
32  for (T_PointerTypeUnsigned i = counter; i < max_val; i++) {
33  if (pointer_map.find(i) == pointer_map.end()) {
34  counter = i + 1;
35  return (T_PointerType)i;
36  }
37  }
38  for (T_PointerTypeUnsigned i = min_val; i < counter; i++) {
39  if (pointer_map.find(i) == pointer_map.end()) {
40  counter = i + 1;
41  return (T_PointerType)i;
42  }
43  }
44  detail::dynamic_check(false, "Could not find free app pointer slot");
45  return 0;
46  }
47 
48 public:
50  {
51  // ensure we can't use app pointer 0 as this is sometimes confused as null
52  // by the sandbox
53  pointer_map[0] = nullptr;
54  }
55 
56  T_PointerType get_app_pointer_idx(void* ptr)
57  {
58  RLBOX_ACQUIRE_UNIQUE_GUARD(lock, map_mutex);
59  T_PointerType idx = get_unused_index();
60  T_PointerTypeUnsigned idx_int = (T_PointerTypeUnsigned)idx;
61  pointer_map[idx_int] = ptr;
62  return idx;
63  }
64 
65  void remove_app_ptr(T_PointerType idx)
66  {
67  RLBOX_ACQUIRE_UNIQUE_GUARD(lock, map_mutex);
68  T_PointerTypeUnsigned idx_int = (T_PointerTypeUnsigned)idx;
69  auto it = pointer_map.find(idx_int);
70  detail::dynamic_check(it != pointer_map.end(),
71  "Error: removing a non-existing app pointer");
72  pointer_map.erase(it);
73  }
74 
75  void* lookup_index(T_PointerType idx)
76  {
77  RLBOX_ACQUIRE_SHARED_GUARD(lock, map_mutex);
78  T_PointerTypeUnsigned idx_int = (T_PointerTypeUnsigned)idx;
79  auto it = pointer_map.find(idx_int);
80  detail::dynamic_check(it != pointer_map.end(),
81  "Error: looking up a non-existing app pointer");
82  return it->second;
83  }
84 };
85 
86 }
Definition: rlbox_app_pointer.hpp:19