Browse Source

uorb: add uorb_unadvertise method

This is necessary when using multiple instances of a topic. However it does
not free the underlying resources, as it is assumed they will be used again
at a later point.
sbg
Beat Küng 9 years ago committed by Lorenz Meier
parent
commit
9da537c092
  1. 1
      src/modules/uORB/Publication.cpp
  2. 5
      src/modules/uORB/uORB.cpp
  3. 5
      src/modules/uORB/uORB.h
  4. 24
      src/modules/uORB/uORBDevices_nuttx.cpp
  5. 5
      src/modules/uORB/uORBDevices_nuttx.hpp
  6. 24
      src/modules/uORB/uORBDevices_posix.cpp
  7. 5
      src/modules/uORB/uORBDevices_posix.hpp
  8. 5
      src/modules/uORB/uORBManager.cpp
  9. 8
      src/modules/uORB/uORBManager.hpp

1
src/modules/uORB/Publication.cpp

@ -96,6 +96,7 @@ void PublicationBase::update(void *data)
PublicationBase::~PublicationBase() PublicationBase::~PublicationBase()
{ {
orb_unadvertise(getHandle());
} }
PublicationNode::PublicationNode(const struct orb_metadata *meta, PublicationNode::PublicationNode(const struct orb_metadata *meta,

5
src/modules/uORB/uORB.cpp

@ -51,6 +51,11 @@ orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *da
return uORB::Manager::get_instance()->orb_advertise_multi(meta, data, instance, priority); return uORB::Manager::get_instance()->orb_advertise_multi(meta, data, instance, priority);
} }
int orb_unadvertise(orb_advert_t handle)
{
return uORB::Manager::get_instance()->orb_unadvertise(handle);
}
int orb_publish_auto(const struct orb_metadata *meta, orb_advert_t *handle, const void *data, int *instance, int orb_publish_auto(const struct orb_metadata *meta, orb_advert_t *handle, const void *data, int *instance,
int priority) int priority)
{ {

5
src/modules/uORB/uORB.h

@ -142,6 +142,11 @@ extern orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *d
extern orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, extern orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance,
int priority) __EXPORT; int priority) __EXPORT;
/**
* @see uORB::Manager::orb_unadvertise()
*/
extern int orb_unadvertise(orb_advert_t handle) __EXPORT;
/** /**
* Advertise as the publisher of a topic. * Advertise as the publisher of a topic.
* *

24
src/modules/uORB/uORBDevices_nuttx.cpp

@ -336,6 +336,30 @@ uORB::DeviceNode::publish
return OK; return OK;
} }
int uORB::DeviceNode::unadvertise(orb_advert_t handle)
{
if (handle == nullptr) {
return -EINVAL;
}
uORB::DeviceNode *devnode = (uORB::DeviceNode *)handle;
/*
* We are cheating a bit here. First, with the current implementation, we can only
* have multiple publishers for instance 0. In this case the caller will have
* instance=nullptr and _published has no effect at all. Thus no unadvertise is
* necessary.
* In case of multiple instances, we have at most 1 publisher per instance and
* we can signal an instance as 'free' by setting _published to false.
* We never really free the DeviceNode, for this we would need reference counting
* of subscribers and publishers. But we also do not have a leak since future
* publishers reuse the same DeviceNode object.
*/
devnode->_published = false;
return PX4_OK;
}
pollevent_t pollevent_t
uORB::DeviceNode::poll_state(struct file *filp) uORB::DeviceNode::poll_state(struct file *filp)
{ {

5
src/modules/uORB/uORBDevices_nuttx.hpp

@ -122,6 +122,8 @@ public:
const void *data const void *data
); );
static int unadvertise(orb_advert_t handle);
/** /**
* processes a request for add subscription from remote * processes a request for add subscription from remote
* @param rateInHz * @param rateInHz
@ -184,7 +186,8 @@ private:
uint8_t *_data; /**< allocated object buffer */ uint8_t *_data; /**< allocated object buffer */
hrt_abstime _last_update; /**< time the object was last updated */ hrt_abstime _last_update; /**< time the object was last updated */
volatile unsigned _generation; /**< object generation count */ volatile unsigned _generation; /**< object generation count */
pid_t _publisher; /**< if nonzero, current publisher */ pid_t _publisher; /**< if nonzero, current publisher. Only used inside the advertise call.
We allow one publisher to have an open file descriptor at the same time. */
const int _priority; /**< priority of topic */ const int _priority; /**< priority of topic */
bool _published; /**< has ever data been published */ bool _published; /**< has ever data been published */

24
src/modules/uORB/uORBDevices_posix.cpp

@ -352,6 +352,30 @@ uORB::DeviceNode::publish(const orb_metadata *meta, orb_advert_t handle, const v
return PX4_OK; return PX4_OK;
} }
int uORB::DeviceNode::unadvertise(orb_advert_t handle)
{
if (handle == nullptr) {
return -EINVAL;
}
uORB::DeviceNode *devnode = (uORB::DeviceNode *)handle;
/*
* We are cheating a bit here. First, with the current implementation, we can only
* have multiple publishers for instance 0. In this case the caller will have
* instance=nullptr and _published has no effect at all. Thus no unadvertise is
* necessary.
* In case of multiple instances, we have at most 1 publisher per instance and
* we can signal an instance as 'free' by setting _published to false.
* We never really free the DeviceNode, for this we would need reference counting
* of subscribers and publishers. But we also do not have a leak since future
* publishers reuse the same DeviceNode object.
*/
devnode->_published = false;
return PX4_OK;
}
pollevent_t pollevent_t
uORB::DeviceNode::poll_state(device::file_t *filp) uORB::DeviceNode::poll_state(device::file_t *filp)
{ {

5
src/modules/uORB/uORBDevices_posix.hpp

@ -59,6 +59,8 @@ public:
static ssize_t publish(const orb_metadata *meta, orb_advert_t handle, const void *data); static ssize_t publish(const orb_metadata *meta, orb_advert_t handle, const void *data);
static int unadvertise(orb_advert_t handle);
/** /**
* processes a request for add subscription from remote * processes a request for add subscription from remote
* @param rateInHz * @param rateInHz
@ -122,7 +124,8 @@ private:
uint8_t *_data; /**< allocated object buffer */ uint8_t *_data; /**< allocated object buffer */
hrt_abstime _last_update; /**< time the object was last updated */ hrt_abstime _last_update; /**< time the object was last updated */
volatile unsigned _generation; /**< object generation count */ volatile unsigned _generation; /**< object generation count */
unsigned long _publisher; /**< if nonzero, current publisher */ unsigned long _publisher; /**< if nonzero, current publisher. Only used inside the advertise call.
We allow one publisher to have an open file descriptor at the same time. */
const int _priority; /**< priority of topic */ const int _priority; /**< priority of topic */
bool _published; /**< has ever data been published */ bool _published; /**< has ever data been published */

5
src/modules/uORB/uORBManager.cpp

@ -129,6 +129,11 @@ orb_advert_t uORB::Manager::orb_advertise_multi(const struct orb_metadata *meta,
return advertiser; return advertiser;
} }
int uORB::Manager::orb_unadvertise(orb_advert_t handle)
{
return uORB::DeviceNode::unadvertise(handle);
}
int uORB::Manager::orb_subscribe(const struct orb_metadata *meta) int uORB::Manager::orb_subscribe(const struct orb_metadata *meta)
{ {
return node_open(PUBSUB, meta, nullptr, false); return node_open(PUBSUB, meta, nullptr, false);

8
src/modules/uORB/uORBManager.hpp

@ -130,6 +130,14 @@ public:
int priority) ; int priority) ;
/**
* Unadvertise a topic.
*
* @param handle handle returned by orb_advertise or orb_advertise_multi.
* @return 0 on success
*/
int orb_unadvertise(orb_advert_t handle);
/** /**
* Publish new data to a topic. * Publish new data to a topic.
* *

Loading…
Cancel
Save