From 1a57488ac68e147389050752e8b6b9bbf6620a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Fri, 22 Apr 2016 16:28:23 +0200 Subject: [PATCH] orb: add a separate uORB::Manager::initialize() method This fixes a race condition: uORB::Manager::get_instance() is used in a multi-thread context, but the singleton initialization was not thread-safe. Further, this avoids having to check for nullptr every time the singleton is accessed. uORB::Manager::initialize() is called when uorb is started. No one else accesses the singleton before that point, because it is only used in the orb_* methods, and in muorb. Both require uorb to be started already when they are used. --- src/modules/uORB/uORBMain.cpp | 6 ++++++ src/modules/uORB/uORBManager.cpp | 4 ++-- src/modules/uORB/uORBManager.hpp | 12 +++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/modules/uORB/uORBMain.cpp b/src/modules/uORB/uORBMain.cpp index 0769ea6adf..cdc18e23bd 100644 --- a/src/modules/uORB/uORBMain.cpp +++ b/src/modules/uORB/uORBMain.cpp @@ -33,6 +33,7 @@ #include #include "uORBDevices.hpp" +#include "uORBManager.hpp" #include "uORB.h" #include "uORBCommon.hpp" @@ -70,6 +71,11 @@ uorb_main(int argc, char *argv[]) return 0; } + if (!uORB::Manager::initialize()) { + PX4_ERR("uorb manager alloc failed"); + return -ENOMEM; + } + /* create the driver */ g_dev = new uORB::DeviceMaster(uORB::PUBSUB); diff --git a/src/modules/uORB/uORBManager.cpp b/src/modules/uORB/uORBManager.cpp index 601d8597e2..c1266ba04a 100644 --- a/src/modules/uORB/uORBManager.cpp +++ b/src/modules/uORB/uORBManager.cpp @@ -49,13 +49,13 @@ uORB::Manager *uORB::Manager::_Instance = nullptr; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -uORB::Manager *uORB::Manager::get_instance() +bool uORB::Manager::initialize() { if (_Instance == nullptr) { _Instance = new uORB::Manager(); } - return _Instance; + return _Instance != nullptr; } //----------------------------------------------------------------------------- diff --git a/src/modules/uORB/uORBManager.hpp b/src/modules/uORB/uORBManager.hpp index 93d2f41119..eb02a42b39 100644 --- a/src/modules/uORB/uORBManager.hpp +++ b/src/modules/uORB/uORBManager.hpp @@ -62,11 +62,21 @@ class uORB::Manager : public uORBCommunicator::IChannelRxHandler public: // public interfaces for this class. + /** + * Initialize the singleton. Call this before everything else. + * @return true on success + */ + static bool initialize(); + /** * Method to get the singleton instance for the uORB::Manager. + * Make sure initialize() is called first. * @return uORB::Manager* */ - static uORB::Manager *get_instance(); + static uORB::Manager *get_instance() + { + return _Instance; + } // ==== uORB interface methods ==== /**