ROS 2 rclcpp + rcl - rolling  rolling-4d14414d
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 <unordered_set>
27 #include <utility>
28 #include <vector>
29 #include <stdexcept>
30 
31 #include "rcl/context.h"
32 #include "rcl/guard_condition.h"
33 #include "rcl/wait.h"
34 #include "rclcpp/init_options.hpp"
35 #include "rclcpp/macros.hpp"
36 #include "rclcpp/visibility_control.hpp"
37 
38 namespace rclcpp
39 {
40 namespace graph_listener
41 {
42 class GraphListener;
43 } // namespace graph_listener
44 
46 class ContextAlreadyInitialized : public std::runtime_error
47 {
48 public:
50  : std::runtime_error("context is already initialized") {}
51 };
52 
55 
57 {
58  friend class Context;
59 
60 public:
61  using ShutdownCallbackType = std::function<void ()>;
62 
63 private:
64  std::weak_ptr<ShutdownCallbackType> callback;
65 };
66 
69 
71 
79 class Context : public std::enable_shared_from_this<Context>
80 {
81 public:
82  RCLCPP_SMART_PTR_DEFINITIONS(Context)
83 
84 
91  RCLCPP_PUBLIC
92  Context();
93 
94  RCLCPP_PUBLIC
95  virtual
96  ~Context();
97 
99 
133  RCLCPP_PUBLIC
134  virtual
135  void
136  init(
137  int argc,
138  char const * const * argv,
139  const rclcpp::InitOptions & init_options = rclcpp::InitOptions());
140 
142 
151  RCLCPP_PUBLIC
152  bool
153  is_valid() const;
154 
156  RCLCPP_PUBLIC
157  const rclcpp::InitOptions &
158  get_init_options() const;
159 
161  RCLCPP_PUBLIC
164 
166  RCLCPP_PUBLIC
167  size_t
168  get_domain_id() const;
169 
171 
174  RCLCPP_PUBLIC
175  std::string
176  shutdown_reason() const;
177 
179 
203  RCLCPP_PUBLIC
204  virtual
205  bool
206  shutdown(const std::string & reason);
207 
208  using OnShutdownCallback = OnShutdownCallbackHandle::ShutdownCallbackType;
209 
211 
229  RCLCPP_PUBLIC
230  virtual
231  OnShutdownCallback
232  on_shutdown(OnShutdownCallback callback);
233 
235 
253  RCLCPP_PUBLIC
254  virtual
256  add_on_shutdown_callback(OnShutdownCallback callback);
257 
259 
263  RCLCPP_PUBLIC
264  virtual
265  bool
266  remove_on_shutdown_callback(const OnShutdownCallbackHandle & callback_handle);
267 
268  using PreShutdownCallback = PreShutdownCallbackHandle::ShutdownCallbackType;
269 
271 
280  RCLCPP_PUBLIC
281  virtual
283  add_pre_shutdown_callback(PreShutdownCallback callback);
284 
286 
290  RCLCPP_PUBLIC
291  virtual
292  bool
294 
296 
299  RCLCPP_PUBLIC
300  std::vector<OnShutdownCallback>
302 
304 
307  RCLCPP_PUBLIC
308  std::vector<PreShutdownCallback>
310 
312  RCLCPP_PUBLIC
313  std::shared_ptr<rcl_context_t>
314  get_rcl_context();
315 
316  RCLCPP_PUBLIC
317  std::shared_ptr<rclcpp::graph_listener::GraphListener>
318  get_graph_listener();
319 
321 
332  RCLCPP_PUBLIC
333  bool
334  sleep_for(const std::chrono::nanoseconds & nanoseconds);
335 
337  RCLCPP_PUBLIC
338  void
340 
342  template<typename SubContext, typename ... Args>
343  std::shared_ptr<SubContext>
344  get_sub_context(Args && ... args)
345  {
346  std::lock_guard<std::recursive_mutex> lock(sub_contexts_mutex_);
347 
348  std::type_index type_i(typeid(SubContext));
349  std::shared_ptr<SubContext> sub_context;
350  auto it = sub_contexts_.find(type_i);
351  if (it == sub_contexts_.end()) {
352  // It doesn't exist yet, make it
353  sub_context = std::shared_ptr<SubContext>(
354  new SubContext(std::forward<Args>(args) ...),
355  [](SubContext * sub_context_ptr) {
356  delete sub_context_ptr;
357  });
358  sub_contexts_[type_i] = sub_context;
359  } else {
360  // It exists, get it out and cast it.
361  sub_context = std::static_pointer_cast<SubContext>(it->second);
362  }
363  return sub_context;
364  }
365 
366 protected:
367  // Called by constructor and destructor to clean up by finalizing the
368  // shutdown rcl context and preparing for a new init cycle.
369  RCLCPP_PUBLIC
370  void
371  clean_up();
372 
373 private:
374  RCLCPP_DISABLE_COPY(Context)
375 
376  // This mutex is recursive so that the destructor can ensure atomicity
377  // between is_initialized and shutdown.
378  mutable std::recursive_mutex init_mutex_;
379  std::shared_ptr<rcl_context_t> rcl_context_;
380  rclcpp::InitOptions init_options_;
381  std::string shutdown_reason_;
382 
383  // Keep shared ownership of the global logging mutex.
384  std::shared_ptr<std::recursive_mutex> logging_mutex_;
385 
386  std::unordered_map<std::type_index, std::shared_ptr<void>> sub_contexts_;
387  // This mutex is recursive so that the constructor of a sub context may
388  // attempt to acquire another sub context.
389  std::recursive_mutex sub_contexts_mutex_;
390 
391  std::vector<std::shared_ptr<OnShutdownCallback>> on_shutdown_callbacks_;
392  mutable std::recursive_mutex on_shutdown_callbacks_mutex_;
393 
394  std::vector<std::shared_ptr<PreShutdownCallback>> pre_shutdown_callbacks_;
395  mutable std::recursive_mutex pre_shutdown_callbacks_mutex_;
396 
398  std::condition_variable interrupt_condition_variable_;
400  std::mutex interrupt_mutex_;
401 
403  std::shared_ptr<rclcpp::graph_listener::GraphListener> graph_listener_;
404 
406  std::shared_ptr<WeakContextsWrapper> weak_contexts_;
407 
408  enum class ShutdownType
409  {
410  pre_shutdown,
412  };
413 
414  using ShutdownCallback = ShutdownCallbackHandle::ShutdownCallbackType;
415 
416  template<ShutdownType shutdown_type>
417  RCLCPP_LOCAL
418  ShutdownCallbackHandle
419  add_shutdown_callback(
420  ShutdownCallback callback);
421 
422  template<ShutdownType shutdown_type>
423  RCLCPP_LOCAL
424  bool
425  remove_shutdown_callback(
426  const ShutdownCallbackHandle & callback_handle);
427 
428  template<ShutdownType shutdown_type>
429  RCLCPP_LOCAL
430  std::vector<rclcpp::Context::ShutdownCallback>
431  get_shutdown_callback() const;
432 };
433 
435 
438 RCLCPP_PUBLIC
439 std::vector<Context::SharedPtr>
440 get_contexts();
441 
442 } // namespace rclcpp
443 
444 #endif // RCLCPP__CONTEXT_HPP_
Thrown when init is called on an already initialized context.
Definition: context.hpp:47
Context which encapsulates shared state between nodes and other similar entities.
Definition: context.hpp:80
std::shared_ptr< SubContext > get_sub_context(Args &&... args)
Return a singleton instance for the SubContext type, constructing one if necessary.
Definition: context.hpp:344
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:529
RCLCPP_PUBLIC void interrupt_all_sleep_for()
Interrupt any blocking sleep_for calls, causing them to return immediately and return true.
Definition: context.cpp:546
virtual RCLCPP_PUBLIC OnShutdownCallback on_shutdown(OnShutdownCallback callback)
Add a on_shutdown callback to be called when shutdown is called for this context.
Definition: context.cpp:391
virtual RCLCPP_PUBLIC OnShutdownCallbackHandle add_on_shutdown_callback(OnShutdownCallback callback)
Add a on_shutdown callback to be called when shutdown is called for this context.
Definition: context.cpp:398
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 PreShutdownCallbackHandle add_pre_shutdown_callback(PreShutdownCallback callback)
Add a pre_shutdown callback to be called before shutdown is called for this context.
Definition: context.cpp:410
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:517
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:560
RCLCPP_PUBLIC 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.