rclcpp  master
C++ ROS Client Library API
context.hpp
Go to the documentation of this file.
1 // Copyright 2014 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RCLCPP__CONTEXT_HPP_
16 #define RCLCPP__CONTEXT_HPP_
17 
18 #include <condition_variable>
19 #include <functional>
20 #include <memory>
21 #include <mutex>
22 #include <string>
23 #include <typeindex>
24 #include <typeinfo>
25 #include <unordered_map>
26 #include <utility>
27 #include <vector>
28 
29 #include "rcl/context.h"
30 #include "rcl/guard_condition.h"
31 #include "rcl/wait.h"
32 #include "rclcpp/init_options.hpp"
33 #include "rclcpp/macros.hpp"
35 
36 namespace rclcpp
37 {
38 
41 {
42 public:
44  : std::runtime_error("context is already initialized") {}
45 };
46 
48 
53 class Context : public std::enable_shared_from_this<Context>
54 {
55 public:
57 
58 
59 
66  Context();
67 
69  virtual
70  ~Context();
71 
73 
105  virtual
106  void
107  init(
108  int argc,
109  char const * const argv[],
110  const rclcpp::InitOptions & init_options = rclcpp::InitOptions());
111 
113 
123  bool
124  is_valid() const;
125 
128  const rclcpp::InitOptions &
129  get_init_options() const;
130 
134  get_init_options();
135 
137 
142  shutdown_reason();
143 
145 
165  virtual
166  bool
167  shutdown(const std::string & reason);
168 
170 
172 
191  virtual
194 
196 
202  get_on_shutdown_callbacks() const;
203 
205 
211  get_on_shutdown_callbacks();
212 
216  get_rcl_context();
217 
219 
231  bool
233 
236  virtual
237  void
238  interrupt_all_sleep_for();
239 
241 
266  get_interrupt_guard_condition(rcl_wait_set_t * wait_set);
267 
269 
284  void
285  release_interrupt_guard_condition(rcl_wait_set_t * wait_set);
286 
289  void
290  release_interrupt_guard_condition(rcl_wait_set_t * wait_set, const std::nothrow_t &) noexcept;
291 
294  virtual
295  void
296  interrupt_all_wait_sets();
297 
299  template<typename SubContext, typename ... Args>
301  get_sub_context(Args && ... args)
302  {
303  std::lock_guard<std::recursive_mutex> lock(sub_contexts_mutex_);
304 
305  std::type_index type_i(typeid(SubContext));
306  std::shared_ptr<SubContext> sub_context;
307  auto it = sub_contexts_.find(type_i);
308  if (it == sub_contexts_.end()) {
309  // It doesn't exist yet, make it
310  sub_context = std::shared_ptr<SubContext>(
311  new SubContext(std::forward<Args>(args) ...),
312  [](SubContext * sub_context_ptr) {
313  delete sub_context_ptr;
314  });
315  sub_contexts_[type_i] = sub_context;
316  } else {
317  // It exists, get it out and cast it.
318  sub_context = std::static_pointer_cast<SubContext>(it->second);
319  }
320  return sub_context;
321  }
322 
323 protected:
324  // Called by constructor and destructor to clean up by finalizing the
325  // shutdown rcl context and preparing for a new init cycle.
327  virtual
328  void
329  clean_up();
330 
331 private:
332  RCLCPP_DISABLE_COPY(Context)
333 
334  // This mutex is recursive so that the destructor can ensure atomicity
335  // between is_initialized and shutdown.
336  std::recursive_mutex init_mutex_;
337  std::shared_ptr<rcl_context_t> rcl_context_;
338  rclcpp::InitOptions init_options_;
339  std::string shutdown_reason_;
340 
342  // This mutex is recursive so that the constructor of a sub context may
343  // attempt to acquire another sub context.
344  std::recursive_mutex sub_contexts_mutex_;
345 
346  std::vector<OnShutdownCallback> on_shutdown_callbacks_;
347  std::mutex on_shutdown_callbacks_mutex_;
348 
350  std::condition_variable interrupt_condition_variable_;
352  std::mutex interrupt_mutex_;
353 
355  std::mutex interrupt_guard_cond_handles_mutex_;
358 };
359 
361 
366 get_contexts();
367 
368 } // namespace rclcpp
369 
370 #endif // RCLCPP__CONTEXT_HPP_
#define RCLCPP_DISABLE_COPY(...)
Definition: macros.hpp:26
Context which encapsulates shared state between nodes and other similar entities. ...
Definition: context.hpp:53
Definition: allocator_common.hpp:24
bool shutdown(rclcpp::Context::SharedPtr context=nullptr, const std::string &reason="user called rclcpp::shutdown()")
Shutdown rclcpp context, invalidating it for derived entities.
void init(int argc, char const *const argv[], const InitOptions &init_options=InitOptions())
Initialize communications via the rmw implementation and set up a global signal handler.
bool sleep_for(const std::chrono::nanoseconds &nanoseconds, rclcpp::Context::SharedPtr context=nullptr)
Use the global condition variable to block for the specified amount of time.
#define RCLCPP_SMART_PTR_DEFINITIONS(...)
Definition: macros.hpp:36
std::shared_ptr< SubContext > get_sub_context(Args &&... args)
Return a singleton instance for the SubContext type, constructing one if necessary.
Definition: context.hpp:301
void on_shutdown(std::function< void()> callback, rclcpp::Context::SharedPtr context=nullptr)
Register a function to be called when shutdown is called on the context.
T static_pointer_cast(T... args)
#define RCLCPP_PUBLIC
Definition: visibility_control.hpp:50
Thrown when init is called on an already initialized context.
Definition: context.hpp:40
ContextAlreadyInitialized()
Definition: context.hpp:43
Encapsulation of options for initializing rclcpp.
Definition: init_options.hpp:27
std::vector< Context::SharedPtr > get_contexts()
Return a copy of the list of context shared pointers.