From c0e3ab632e36e42c2794f7a785945594481a70ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Mon, 23 May 2016 15:31:22 +0200 Subject: [PATCH] orb: proper locking for DeviceNode::{add,remove}_internal_subscriber --- src/modules/uORB/uORBDevices_nuttx.cpp | 16 ++++++++++++++-- src/modules/uORB/uORBDevices_posix.cpp | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/modules/uORB/uORBDevices_nuttx.cpp b/src/modules/uORB/uORBDevices_nuttx.cpp index 5f9df9791a..676043a79f 100644 --- a/src/modules/uORB/uORBDevices_nuttx.cpp +++ b/src/modules/uORB/uORBDevices_nuttx.cpp @@ -575,11 +575,17 @@ uORB::DeviceNode::print_statistics(bool reset) //----------------------------------------------------------------------------- void uORB::DeviceNode::add_internal_subscriber() { - _subscriber_count++; uORBCommunicator::IChannel *ch = uORB::Manager::get_instance()->get_uorb_communicator(); + lock(); + _subscriber_count++; + if (ch != nullptr && _subscriber_count > 0) { + unlock(); //make sure we cannot deadlock if add_subscription calls back into DeviceNode ch->add_subscription(_meta->o_name, 1); + + } else { + unlock(); } } @@ -587,11 +593,17 @@ void uORB::DeviceNode::add_internal_subscriber() //----------------------------------------------------------------------------- void uORB::DeviceNode::remove_internal_subscriber() { - _subscriber_count--; uORBCommunicator::IChannel *ch = uORB::Manager::get_instance()->get_uorb_communicator(); + lock(); + _subscriber_count--; + if (ch != nullptr && _subscriber_count == 0) { + unlock(); //make sure we cannot deadlock if remove_subscription calls back into DeviceNode ch->remove_subscription(_meta->o_name); + + } else { + unlock(); } } diff --git a/src/modules/uORB/uORBDevices_posix.cpp b/src/modules/uORB/uORBDevices_posix.cpp index aa98aacb90..95b35dcce3 100644 --- a/src/modules/uORB/uORBDevices_posix.cpp +++ b/src/modules/uORB/uORBDevices_posix.cpp @@ -579,11 +579,17 @@ uORB::DeviceNode::print_statistics(bool reset) //----------------------------------------------------------------------------- void uORB::DeviceNode::add_internal_subscriber() { - _subscriber_count++; uORBCommunicator::IChannel *ch = uORB::Manager::get_instance()->get_uorb_communicator(); + lock(); + _subscriber_count++; + if (ch != nullptr && _subscriber_count > 0) { + unlock(); //make sure we cannot deadlock if add_subscription calls back into DeviceNode ch->add_subscription(_meta->o_name, 1); + + } else { + unlock(); } } @@ -591,11 +597,17 @@ void uORB::DeviceNode::add_internal_subscriber() //----------------------------------------------------------------------------- void uORB::DeviceNode::remove_internal_subscriber() { - _subscriber_count--; uORBCommunicator::IChannel *ch = uORB::Manager::get_instance()->get_uorb_communicator(); + lock(); + _subscriber_count--; + if (ch != nullptr && _subscriber_count == 0) { + unlock(); //make sure we cannot deadlock if remove_subscription calls back into DeviceNode ch->remove_subscription(_meta->o_name); + + } else { + unlock(); } }