refactor orb: uORB::Manager is responsible for the DeviceMaster objects

This has the following benefits:
- Manager can ensure that there is at most one instance of DeviceMaster
  per Flavor
- The Manager needs access to (static) data of DeviceMaster already.
  This will make it easier to access this data in a non-static way, and
  does not introduce new dependencies.
This commit is contained in:
Beat Küng 2016-04-29 13:01:01 +02:00 committed by Lorenz Meier
parent 2dd29ec4a1
commit 45a0a7c5ab
6 changed files with 59 additions and 12 deletions

View File

@ -52,8 +52,10 @@ static const unsigned orb_maxpath = 64;
const int ERROR = -1; const int ERROR = -1;
enum Flavor { enum Flavor {
PUBSUB, PUBSUB = 0,
PARAM PARAM,
Flavor_count
}; };
struct orb_advertdata { struct orb_advertdata {

View File

@ -45,6 +45,7 @@ namespace uORB
{ {
class DeviceNode; class DeviceNode;
class DeviceMaster; class DeviceMaster;
class Manager;
} }
/** /**
@ -259,6 +260,8 @@ public:
DeviceMaster(Flavor f); DeviceMaster(Flavor f);
virtual ~DeviceMaster(); virtual ~DeviceMaster();
friend class uORB::Manager;
static uORB::DeviceNode *GetDeviceNode(const char *node_name); static uORB::DeviceNode *GetDeviceNode(const char *node_name);
virtual int ioctl(struct file *filp, int cmd, unsigned long arg); virtual int ioctl(struct file *filp, int cmd, unsigned long arg);
private: private:

View File

@ -43,6 +43,7 @@ namespace uORB
{ {
class DeviceNode; class DeviceNode;
class DeviceMaster; class DeviceMaster;
class Manager;
} }
class uORB::DeviceNode : public device::VDev class uORB::DeviceNode : public device::VDev
@ -193,6 +194,8 @@ public:
DeviceMaster(Flavor f); DeviceMaster(Flavor f);
virtual ~DeviceMaster(); virtual ~DeviceMaster();
friend class uORB::Manager;
static uORB::DeviceNode *GetDeviceNode(const char *node_name); static uORB::DeviceNode *GetDeviceNode(const char *node_name);
virtual int ioctl(device::file_t *filp, int cmd, unsigned long arg); virtual int ioctl(device::file_t *filp, int cmd, unsigned long arg);

View File

@ -72,18 +72,10 @@ uorb_main(int argc, char *argv[])
} }
/* create the driver */ /* create the driver */
g_dev = new uORB::DeviceMaster(uORB::PUBSUB); g_dev = uORB::Manager::get_instance()->get_device_master(uORB::PUBSUB);
if (g_dev == nullptr) { if (g_dev == nullptr) {
PX4_ERR("driver alloc failed"); return -errno;
return -ENOMEM;
}
if (OK != g_dev->init()) {
PX4_ERR("driver init failed");
delete g_dev;
g_dev = nullptr;
return -EIO;
} }
return OK; return OK;

View File

@ -64,6 +64,9 @@ bool uORB::Manager::initialize()
uORB::Manager::Manager() uORB::Manager::Manager()
: _comm_channel(nullptr) : _comm_channel(nullptr)
{ {
for (int i = 0; i < Flavor_count; ++i) {
_device_masters[i] = nullptr;
}
#ifdef ORB_USE_PUBLISHER_RULES #ifdef ORB_USE_PUBLISHER_RULES
const char *file_name = "./rootfs/orb_publisher.rules"; const char *file_name = "./rootfs/orb_publisher.rules";
@ -81,6 +84,39 @@ uORB::Manager::Manager()
} }
uORB::Manager::~Manager()
{
for (int i = 0; i < Flavor_count; ++i) {
if (_device_masters[i]) {
delete _device_masters[i];
}
}
}
uORB::DeviceMaster *uORB::Manager::get_device_master(Flavor flavor)
{
if (!_device_masters[flavor]) {
_device_masters[flavor] = new DeviceMaster(flavor);
if (_device_masters[flavor]) {
int ret = _device_masters[flavor]->init();
if (ret != PX4_OK) {
PX4_ERR("Initialization of DeviceMaster failed (%i)", ret);
errno = -ret;
delete _device_masters[flavor];
_device_masters[flavor] = nullptr;
}
} else {
PX4_ERR("Failed to allocate DeviceMaster");
errno = ENOMEM;
}
}
return _device_masters[flavor];
}
int uORB::Manager::orb_exists(const struct orb_metadata *meta, int instance) int uORB::Manager::orb_exists(const struct orb_metadata *meta, int instance)
{ {
/* /*

View File

@ -78,6 +78,14 @@ public:
return _Instance; return _Instance;
} }
/**
* Get the DeviceMaster for a given Flavor. If it does not exist,
* it will be created and initialized.
* Note: the first call to this is not thread-safe.
* @return nullptr if initialization failed (and errno will be set)
*/
uORB::DeviceMaster *get_device_master(Flavor flavor);
// ==== uORB interface methods ==== // ==== uORB interface methods ====
/** /**
* Advertise as the publisher of a topic. * Advertise as the publisher of a topic.
@ -399,8 +407,11 @@ private: // data members
uORBCommunicator::IChannel *_comm_channel; uORBCommunicator::IChannel *_comm_channel;
ORBSet _remote_subscriber_topics; ORBSet _remote_subscriber_topics;
DeviceMaster *_device_masters[Flavor_count]; ///< Allow at most one DeviceMaster per Flavor
private: //class methods private: //class methods
Manager(); Manager();
~Manager();
/** /**
* Interface to process a received AddSubscription from remote. * Interface to process a received AddSubscription from remote.