ros2 / rmw_cyclonedds

ROS 2 RMW layer for Eclipse Cyclone DDS
Apache License 2.0
107 stars 89 forks source link

abort when running with SHM(TRUE) and MultiThreadedExecutor(CallbackGroupType::Reentrant) #495

Open binbowang1987 opened 1 month ago

binbowang1987 commented 1 month ago

Bug report

Required Info:

Steps to reproduce issue

Test.msg

uint8[133] data
// publisher
class MinimalPublisher : public rclcpp::Node
{
public:
  MinimalPublisher()
  : Node("minimal_publisher"), count_(0)
  {
    publisher_ = this->create_publisher<examples_rclcpp_minimal_publisher::msg::Test>("topic", 100);
    timer_ = this->create_wall_timer(
      10ms, std::bind(&MinimalPublisher::timer_callback, this));
  }

private:
  void timer_callback()
  {
    for(int i = 0;i<10;i++) {
      auto message = examples_rclcpp_minimal_publisher::msg::Test();
      publisher_->publish(message);
    }
  }
  rclcpp::TimerBase::SharedPtr timer_;
  rclcpp::Publisher<examples_rclcpp_minimal_publisher::msg::Test>::SharedPtr publisher_;
  size_t count_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalPublisher>());
  rclcpp::shutdown();
  return 0;
}
// subscriber
class MinimalSubscriber : public rclcpp::Node
{
public:
  MinimalSubscriber()
  : Node("minimal_subscriber", rclcpp::NodeOptions())
  {
    rclcpp::CallbackGroup::SharedPtr callbackGroup = 
      this->create_callback_group(rclcpp::CallbackGroupType::Reentrant);

    auto sub_opt = rclcpp::SubscriptionOptions();
    sub_opt.callback_group = callbackGroup;

    subscription_ = this->create_subscription<examples_rclcpp_minimal_publisher::msg::Test>(
      "topic", rclcpp::QoS(10), std::bind(&MinimalSubscriber::topic_callback, this, _1), 
      sub_opt);
  }

private:
  void topic_callback(const examples_rclcpp_minimal_publisher::msg::Test & msg) const
  {
    RCLCPP_INFO(this->get_logger(), "xxxxxx, %ld", msg.data.size());
    usleep(1000*1000);
  }
  rclcpp::Subscription<examples_rclcpp_minimal_publisher::msg::Test>::SharedPtr subscription_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);

  auto node1 = std::make_shared<MinimalSubscriber>();
  rclcpp::executors::MultiThreadedExecutor executor;
  executor.add_node(node1);
  executor.spin();
  rclcpp::shutdown();
  return 0;
}

Expected behavior

Normally Run

Actual behavior

Aborted

Additional information

image

Feature request

Feature description

Implementation considerations

audrow commented 3 weeks ago

FYI @eboasson.

eboasson commented 1 week ago

I have a good idea what's going on here (Iceoryx API's aren't multi-thread safe, while I assumed they were. The hacks in Cyclone that were put in later are not the greatest. I think Cyclone master will do better, but then you need a patched RMW layer.)