CARLA
 
载入中...
搜索中...
未找到
RecurrentSharedFuture.h
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#pragma once
8
9#include "carla/Exception.h"
10#include "carla/Time.h"
11
12#include <boost/optional.hpp>
13#ifdef _MSC_VER
14#pragma warning(push)
15#pragma warning(disable:4583)
16#pragma warning(disable:4582)
17#include <boost/variant2/variant.hpp>
18#pragma warning(pop)
19#else
20#include <boost/variant2/variant.hpp>
21#endif
22
23#include <condition_variable>
24#include <exception>
25#include <map>
26#include <mutex>
27
28namespace carla {
29
30namespace detail {
31
32 class SharedException;
33
34} // namespace detail
35
36 // ===========================================================================
37 // -- RecurrentSharedFuture --------------------------------------------------
38 // ===========================================================================
39
40 /// This class is meant to be used similar to a shared future, but the value
41 /// can be set any number of times.
42 template <typename T>
44 public:
45
47
48 /// Wait until the next value is set. Any number of threads can be waiting
49 /// simultaneously.
50 ///
51 /// @return empty optional if the timeout is met.
52 boost::optional<T> WaitFor(time_duration timeout);
53
54 /// Set the value and notify all waiting threads.
55 template <typename T2>
56 void SetValue(const T2 &value);
57
58 /// Set a exception, this exception will be thrown on all the threads
59 /// waiting.
60 ///
61 /// @note The @a exception will be stored on a SharedException and thrown
62 /// as such.
63 template <typename ExceptionT>
64 void SetException(ExceptionT &&exception);
65
66 private:
67
68 std::mutex _mutex;
69
70 std::condition_variable _cv;
71
72 struct mapped_type {
74 boost::variant2::variant<SharedException, T> value;
75 };
76
77 std::map<const char *, mapped_type> _map;
78 };
79
80 // ===========================================================================
81 // -- RecurrentSharedFuture implementation -----------------------------------
82 // ===========================================================================
83
84namespace detail {
85
86 static thread_local const char thread_tag{};
87
88 class SharedException : public std::exception {
89 public:
90
92 : _exception(std::make_shared<std::runtime_error>("uninitialized SharedException")) {}
93
94 SharedException(std::shared_ptr<std::exception> e)
95 : _exception(std::move(e)) {}
96
97 const char *what() const noexcept override {
98 return _exception->what();
99 }
100
101 std::shared_ptr<std::exception> GetException() const {
102 return _exception;
103 }
104
105 private:
106
107 std::shared_ptr<std::exception> _exception;
108 };
109
110} // namespace detail
111
112 template <typename T>
114 std::unique_lock<std::mutex> lock(_mutex);
115 auto &r = _map[&detail::thread_tag];
116 r.should_wait = true;
117 if (!_cv.wait_for(lock, timeout.to_chrono(), [&]() { return !r.should_wait; })) {
118 return {};
119 }
120 if (r.value.index() == 0) {
121 throw_exception(boost::variant2::get<SharedException>(r.value));
122 }
123 return boost::variant2::get<T>(std::move(r.value));
124 }
125
126 template <typename T>
127 template <typename T2>
129 std::lock_guard<std::mutex> lock(_mutex);
130 for (auto &pair : _map) {
131 pair.second.should_wait = false;
132 pair.second.value = value;
133 }
134 _cv.notify_all();
135 }
136
137 template <typename T>
138 template <typename ExceptionT>
140 SetValue(SharedException(std::make_shared<ExceptionT>(std::forward<ExceptionT>(e))));
141 }
142
143} // namespace carla
This class is meant to be used similar to a shared future, but the value can be set any number of tim...
std::map< const char *, mapped_type > _map
void SetException(ExceptionT &&exception)
Set a exception, this exception will be thrown on all the threads waiting.
void SetValue(const T2 &value)
Set the value and notify all waiting threads.
boost::optional< T > WaitFor(time_duration timeout)
Wait until the next value is set.
const char * what() const noexcept override
SharedException(std::shared_ptr< std::exception > e)
std::shared_ptr< std::exception > GetException() const
std::shared_ptr< std::exception > _exception
Positive time duration up to milliseconds resolution.
Definition Time.h:19
constexpr auto to_chrono() const
Definition Time.h:50
static thread_local const char thread_tag
This file contains definitions of common data structures used in traffic manager.
Definition Carla.cpp:133
void throw_exception(const std::exception &e)
Definition Carla.cpp:135
boost::variant2::variant< SharedException, T > value