ROS 2 rclcpp + rcl - rolling  rolling-20536064
ROS 2 C++ Client Library with ROS Client Library
context.hpp
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 #include <stdexcept>
29 
30 #include "rcl/context.h"
31 #include "rcl/guard_condition.h"
32 #include "rcl/wait.h"
33 #include "rclcpp/init_options.hpp"
34 #include "rclcpp/macros.hpp"
35 #include "rclcpp/visibility_control.hpp"
36 
37 namespace rclcpp
38 {
39 namespace graph_listener
40 {
41 class GraphListener;
42 } // namespace graph_listener
43 
45 class ContextAlreadyInitialized : public std::runtime_error
46 {
47 public:
49  : std::runtime_error("context is already initialized") {}
50 };
51 
54 
56 {
57  friend class Context;
58 
59 public:
60  using ShutdownCallbackType = std::function<void ()>;
61 
62 private:
63  std::weak_ptr<ShutdownCallbackType> callback;
64 };
65 
68 
70 
78 class Context : public std::enable_shared_from_this<Context>
79 {
80 public:
81  RCLCPP_SMART_PTR_DEFINITIONS(Context)
82 
83 
90  RCLCPP_PUBLIC
91  Context();
92 
93  RCLCPP_PUBLIC
94  virtual
95  ~Context();
96 
98 
132  RCLCPP_PUBLIC
133  virtual
134  void
135  init(
136  int argc,
137  char const * const * argv,
138  const rclcpp::InitOptions & init_options = rclcpp::InitOptions());
139 
141 
150  RCLCPP_PUBLIC
151  bool
152  is_valid() const;
153 
155  RCLCPP_PUBLIC
156  const rclcpp::InitOptions &
157  get_init_options() const;
158 
160  RCLCPP_PUBLIC
163 
165  RCLCPP_PUBLIC
166  size_t
167  get_domain_id() const;
168 
170 
173  RCLCPP_PUBLIC
174  std::string
175  shutdown_reason() const;
176 
178 
202  RCLCPP_PUBLIC
203  virtual
204  bool
205  shutdown(const std::string & reason);
206 
207  using OnShutdownCallback = OnShutdownCallbackHandle::ShutdownCallbackType;
208 
210 
228  RCLCPP_PUBLIC
229  virtual
230  OnShutdownCallback
231  on_shutdown(const OnShutdownCallback & callback);
232 
234 
252  RCLCPP_PUBLIC
253  virtual
255  add_on_shutdown_callback(const OnShutdownCallback & callback);
256 
258 
262  RCLCPP_PUBLIC
263  virtual
264  bool
265  remove_on_shutdown_callback(const OnShutdownCallbackHandle & callback_handle);
266 
267  using PreShutdownCallback = PreShutdownCallbackHandle::ShutdownCallbackType;
268 
270 
279  RCLCPP_PUBLIC
280  virtual
282  add_pre_shutdown_callback(const PreShutdownCallback & callback);
283 
285 
289  RCLCPP_PUBLIC
290  virtual
291  bool
293 
295 
298  RCLCPP_PUBLIC
299  std::vector<OnShutdownCallback>
301 
303 
306  RCLCPP_PUBLIC
307  std::vector<PreShutdownCallback>
309 
311  RCLCPP_PUBLIC
312  std::shared_ptr<rcl_context_t>
313  get_rcl_context();
314 
315  RCLCPP_PUBLIC
316  std::shared_ptr<rclcpp::graph_listener::GraphListener>
317  get_graph_listener();
318 
320 
331  RCLCPP_PUBLIC
332  bool
333  sleep_for(const std::chrono::nanoseconds & nanoseconds);
334 
336  RCLCPP_PUBLIC
337  void
339 
341  template<typename SubContext, typename ... Args>
342  std::shared_ptr<SubContext>
343  get_sub_context(Args && ... args)
344  {
345  std::lock_guard<std::recursive_mutex> lock(sub_contexts_mutex_);
346 
347  std::type_index type_i(typeid(SubContext));
348  std::shared_ptr<SubContext> sub_context;
349  auto it = sub_contexts_.find(type_i);
350  if (it == sub_contexts_.end()) {
351  // It doesn't exist yet, make it
352  sub_context = std::shared_ptr<SubContext>(
353  new SubContext(std::forward<Args>(args) ...),
354  [](SubContext * sub_context_ptr) {
355  delete sub_context_ptr;
356  });
357  sub_contexts_[type_i] = sub_context;
358  } else {
359  // It exists, get it out and cast it.
360  sub_context = std::static_pointer_cast<SubContext>(it->second);
361  }
362  return sub_context;
363  }
364 
365 protected:
366  // Called by constructor and destructor to clean up by finalizing the
367  // shutdown rcl context and preparing for a new init cycle.
368  RCLCPP_PUBLIC
369  void
370  clean_up();
371 
372 private:
373  RCLCPP_DISABLE_COPY(Context)
374 
375  // This mutex is recursive so that the destructor can ensure atomicity
376  // between is_initialized and shutdown.
377  mutable std::recursive_mutex init_mutex_;
378  std::shared_ptr<rcl_context_t> rcl_context_;
379  rclcpp::InitOptions init_options_;
380  std::string shutdown_reason_;
381 
382  // Keep shared ownership of the global logging mutex.
383  std::shared_ptr<std::recursive_mutex> logging_mutex_;
384 
385  std::unordered_map<std::type_index, std::shared_ptr<void>> sub_contexts_;
386  // This mutex is recursive so that the constructor of a sub context may
387  // attempt to acquire another sub context.
388  std::recursive_mutex sub_contexts_mutex_;
389 
390  std::vector<std::shared_ptr<OnShutdownCallback>> on_shutdown_callbacks_;
391  mutable std::recursive_mutex on_shutdown_callbacks_mutex_;
392 
393  std::vector<std::shared_ptr<PreShutdownCallback>> pre_shutdown_callbacks_;
394  mutable std::recursive_mutex pre_shutdown_callbacks_mutex_;
395 
397  std::condition_variable interrupt_condition_variable_;
399  std::mutex interrupt_mutex_;
400 
402  std::shared_ptr<rclcpp::graph_listener::GraphListener> graph_listener_;
403 
405  std::shared_ptr<WeakContextsWrapper> weak_contexts_;
406 
407  enum class ShutdownType
408  {
409  pre_shutdown,
411  };
412 
413  using ShutdownCallback = ShutdownCallbackHandle::ShutdownCallbackType;
414 
415  template<ShutdownType shutdown_type>
416  RCLCPP_LOCAL
417  ShutdownCallbackHandle
418  add_shutdown_callback(
419  const ShutdownCallback & callback);
420 
421  template<ShutdownType shutdown_type>
422  RCLCPP_LOCAL
423  bool
424  remove_shutdown_callback(
425  const ShutdownCallbackHandle & callback_handle);
426 
427  template<ShutdownType shutdown_type>
428  RCLCPP_LOCAL
429  std::vector<rclcpp::Context::ShutdownCallback>
430  get_shutdown_callback() const;
431 };
432 
434 
437 RCLCPP_PUBLIC
438 std::vector<Context::SharedPtr>
439 get_contexts();
440 
441 } // namespace rclcpp
442 
443 #endif // RCLCPP__CONTEXT_HPP_
Thrown when init is called on an already initialized context.
Definition: context.hpp:46
Context which encapsulates shared state between nodes and other similar entities.
Definition: context.hpp:79
virtual RCLCPP_PUBLIC PreShutdownCallbackHandle add_pre_shutdown_callback(const PreShutdownCallback &callback)
Add a pre_shutdown callback to be called before shutdown is called for this context.
Definition: context.cpp:410
virtual RCLCPP_PUBLIC OnShutdownCallbackHandle add_on_shutdown_callback(const OnShutdownCallback &callback)
Add a on_shutdown callback to be called when shutdown is called for this context.
Definition: context.cpp:398
std::shared_ptr< SubContext > get_sub_context(Args &&... args)
Return a singleton instance for the SubContext type, constructing one if necessary.
Definition: context.hpp:343
virtual RCLCPP_PUBLIC void init(int argc, char const *const *argv, const rclcpp::InitOptions &init_options=rclcpp::InitOptions())
Initialize the context, and the underlying elements like the rcl context.
Definition: context.cpp:194
RCLCPP_PUBLIC std::vector< OnShutdownCallback > get_on_shutdown_callbacks() const
Return the shutdown callbacks.
Definition: context.cpp:482
RCLCPP_PUBLIC std::vector< PreShutdownCallback > get_pre_shutdown_callbacks() const
Return the pre-shutdown callbacks.
Definition: context.cpp:488
RCLCPP_PUBLIC Context()
Default constructor, after which the Context is still not "initialized".
Definition: context.cpp:145
RCLCPP_PUBLIC size_t get_domain_id() const
Return actual domain id.
Definition: context.cpp:302
RCLCPP_PUBLIC std::string shutdown_reason() const
Return the shutdown reason, or empty string if not shutdown.
Definition: context.cpp:313
RCLCPP_PUBLIC const rclcpp::InitOptions & get_init_options() const
Return the init options used during init.
Definition: context.cpp:290
RCLCPP_PUBLIC bool sleep_for(const std::chrono::nanoseconds &nanoseconds)
Sleep for a given period of time or until shutdown() is called.
Definition: context.cpp:530
RCLCPP_PUBLIC void interrupt_all_sleep_for()
Interrupt any blocking sleep_for calls, causing them to return immediately and return true.
Definition: context.cpp:547
virtual RCLCPP_PUBLIC OnShutdownCallback on_shutdown(const OnShutdownCallback &callback)
Add a on_shutdown callback to be called when shutdown is called for this context.
Definition: context.cpp:391
virtual RCLCPP_PUBLIC bool remove_pre_shutdown_callback(const PreShutdownCallbackHandle &callback_handle)
Remove an registered pre_shutdown callback.
Definition: context.cpp:416
RCLCPP_PUBLIC bool is_valid() const
Return true if the context is valid, otherwise false.
Definition: context.cpp:279
virtual RCLCPP_PUBLIC bool remove_on_shutdown_callback(const OnShutdownCallbackHandle &callback_handle)
Remove an registered on_shutdown callbacks.
Definition: context.cpp:404
virtual RCLCPP_PUBLIC bool shutdown(const std::string &reason)
Shutdown the context, making it uninitialized and therefore invalid for derived entities.
Definition: context.cpp:320
RCLCPP_PUBLIC std::shared_ptr< rcl_context_t > get_rcl_context()
Return the internal rcl context.
Definition: context.cpp:518
Encapsulation of options for initializing rclcpp.
Class to manage vector of weak pointers to all created contexts.
Definition: context.cpp:43
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC std::vector< Context::SharedPtr > get_contexts()
Return a copy of the list of context shared pointers.
Definition: context.cpp:561
RCLCPP_PUBLIC void on_shutdown(const std::function< void()> &callback, const rclcpp::Context::SharedPtr &context=rclcpp::contexts::get_global_default_context())
Register a function to be called when shutdown is called on the context.