orb_exists: change semantics from (is published or subscribed) to (is published)

Existing users of orb_exists:
- logger (dynamic subscribe to multi-instances)
- mavlink (orb subscription)
- sdlog2
- preflightcheck (check for home_position)
- wait_for_topic shell command (it's not used)
- orb_group_count() (sensors: dynamic sensor addition)

All use-cases benefit from the changed semantics: they are really only
interested if there is a publisher, not another subscriber.
This commit is contained in:
Beat Küng
2017-10-18 08:40:32 +02:00
committed by Lorenz Meier
parent d83073f016
commit 2f2c0440c4
4 changed files with 37 additions and 6 deletions
+3
View File
@@ -93,4 +93,7 @@
/** Get the minimum interval at which the topic can be seen to be updated for this subscription */ /** Get the minimum interval at which the topic can be seen to be updated for this subscription */
#define ORBIOCGETINTERVAL _ORBIOC(16) #define ORBIOCGETINTERVAL _ORBIOC(16)
/** Check whether the topic is published, sets *(unsigned long *)arg to 1 if published, 0 otherwise */
#define ORBIOCISPUBLISHED _ORBIOC(17)
#endif /* _DRV_UORB_H */ #endif /* _DRV_UORB_H */
+9
View File
@@ -170,6 +170,10 @@ uORB::DeviceNode::open(device::file_t *filp)
return ret; return ret;
} }
if (FILE_FLAGS(filp) == 0) {
return CDev::open(filp);
}
/* can only be pub or sub, not both */ /* can only be pub or sub, not both */
return -EINVAL; return -EINVAL;
} }
@@ -405,6 +409,11 @@ uORB::DeviceNode::ioctl(device::file_t *filp, int cmd, unsigned long arg)
return OK; return OK;
case ORBIOCISPUBLISHED:
*(unsigned long *)arg = _published;
return OK;
default: default:
/* give it to the superclass */ /* give it to the superclass */
return CDev::ioctl(filp, cmd, arg); return CDev::ioctl(filp, cmd, arg);
+23 -3
View File
@@ -131,9 +131,9 @@ int uORB::Manager::orb_exists(const struct orb_metadata *meta, int instance)
return ERROR; return ERROR;
} }
#if __PX4_NUTTX #if defined(__PX4_NUTTX)
struct stat buffer; struct stat buffer;
return stat(path, &buffer); ret = stat(path, &buffer);
#else #else
ret = px4_access(path, F_OK); ret = px4_access(path, F_OK);
@@ -141,8 +141,28 @@ int uORB::Manager::orb_exists(const struct orb_metadata *meta, int instance)
ret = (_remote_topics.find(meta->o_name) != _remote_topics.end()) ? OK : ERROR; ret = (_remote_topics.find(meta->o_name) != _remote_topics.end()) ? OK : ERROR;
} }
return ret;
#endif #endif
if (ret == 0) {
// we know the topic exists, but it's not necessarily advertised/published yet (for example
// if there is only a subscriber)
// The open() will not lead to memory allocations.
int fd = px4_open(path, 0);
if (fd >= 0) {
unsigned long is_published;
if (px4_ioctl(fd, ORBIOCISPUBLISHED, (unsigned long)&is_published) == 0) {
if (!is_published) {
ret = ERROR;
}
}
px4_close(fd);
}
}
return ret;
} }
orb_advert_t uORB::Manager::orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, orb_advert_t uORB::Manager::orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance,
+2 -3
View File
@@ -298,12 +298,11 @@ public:
int orb_stat(int handle, uint64_t *time) ; int orb_stat(int handle, uint64_t *time) ;
/** /**
* Check if a topic has already been created (a publisher or a subscriber exists with * Check if a topic has already been created and published (advertised)
* the given instance).
* *
* @param meta ORB topic metadata. * @param meta ORB topic metadata.
* @param instance ORB instance * @param instance ORB instance
* @return OK if the topic exists, ERROR otherwise with errno set accordingly. * @return OK if the topic exists, ERROR otherwise.
*/ */
int orb_exists(const struct orb_metadata *meta, int instance) ; int orb_exists(const struct orb_metadata *meta, int instance) ;