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.
This commit is contained in:
Beat Küng
2016-04-29 11:15:15 +02:00
committed by Lorenz Meier
parent 1b133931a6
commit 1a57488ac6
3 changed files with 19 additions and 3 deletions
+6
View File
@@ -33,6 +33,7 @@
#include <string.h>
#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);
+2 -2
View File
@@ -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;
}
//-----------------------------------------------------------------------------
+11 -1
View File
@@ -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 ====
/**