bool
MavlinkOrbSubscription::update(uint64_t *time, void *data)
{
	// TODO this is NOT atomic operation, we can get data newer than time
	// if topic was published between orb_stat and orb_copy calls.

	if (!is_published()) {
		return false;
	}

	uint64_t time_topic;

	if (orb_stat(_fd, &time_topic)) {
		/* error getting last topic publication time */
		time_topic = 0;
	}

	if (time_topic == 0 || (time_topic != *time)) {
		if (orb_copy(_topic, _fd, data) == PX4_OK) {
			/* data copied successfully */
			*time = time_topic;
			return true;
		}
	}

	return false;
}
 sequence_t wait_until_published(
     sequence_t sequence,
     sequence_t lastKnownPublished,
     const std::chrono::time_point<Clock, Duration>& timeoutTime) const
 {
     assert(difference(sequence, lastKnownPublished) > 0);
     
     for (sequence_t seq = lastKnownPublished + 1;
          difference(seq, sequence) <= 0;
          ++seq)
     {
         if (!is_published(seq))
         {
             const std::atomic<sequence_t>* const sequences[1] =
                 { &m_published[seq & m_indexMask] };
             sequence_t result =
                 m_waitStrategy.wait_until_published(seq, 1, sequences);
             if (difference(result, seq) < 0)
             {
                 // Timeout. seq is the first non-published sequence
                 return seq - 1;
             }
         }
     }
     return last_published_after(sequence);
 }
 /// \brief
 /// Return the highest sequence number published after the specified
 /// last-known published sequence.
 ///
 /// \param lastKnownPublished
 /// This sequence number is assumed to have already been published.
 /// The initial value passed in here on first call should be sequence_t(-1).
 ///
 /// \return
 /// The last-published sequence number.
 /// This will be equal to \p lastKnownPublished if no additional sequences
 /// have been published.
 sequence_t last_published_after(sequence_t lastKnownPublished) const
 {
     sequence_t seq = lastKnownPublished + 1;
     while (is_published(seq))
     {
         lastKnownPublished = seq;
         ++seq;
     }
     return lastKnownPublished;
 }
bool
MavlinkOrbSubscription::update(void *data)
{
	if (!is_published()) {
		return false;
	}

	if (orb_copy(_topic, _fd, data) != PX4_OK) {
		return false;
	}

	return true;
}
bool
MavlinkOrbSubscription::update_if_changed(void *data)
{
	if (!is_published()) {
		return false;
	}

	bool updated;

	if (orb_check(_fd, &updated) || !updated) {
		return false;
	}

	return update(data);
}
bool
MavlinkOrbSubscription::update(void *data)
{
	if (!is_published()) {
		return false;
	}

	if (orb_copy(_topic, _fd, data)) {
		if (data != nullptr) {
			/* error copying topic data */
			memset(data, 0, _topic->o_size);
		}

		return false;
	}

	return true;
}
 /// \brief
 /// Block the caller until the specified sequence number has been
 /// published.
 ///
 /// This method is called by reader threads waiting to consume
 /// items written to the ring buffer.
 ///
 /// \param sequence
 /// The sequence number to wait for.
 ///
 /// \param lastKnownPublished
 /// This sequence number is assumed to have already been published.
 /// The initial value passed in here on first call should be sequence_t(-1).
 ///
 /// \return
 /// Returns the sequence number of the latest available published
 /// sequence, guaranteed to be equal to or later than the specified
 /// \p sequence parameter.
 ///
 /// \throw std::exception
 /// Throws any exception thrown by \c WaitStrategy::wait_until_published().
 sequence_t wait_until_published(
     sequence_t sequence,
     sequence_t lastKnownPublished) const
 {
     assert(difference(sequence, lastKnownPublished) > 0);
     
     for (sequence_t seq = lastKnownPublished + 1;
          difference(seq, sequence) <= 0;
          ++seq)
     {
         if (!is_published(seq))
         {
             const std::atomic<sequence_t>* const sequences[1] =
                 { &m_published[seq & m_indexMask] };
             m_waitStrategy.wait_until_published(seq, 1, sequences);
         }
     }
     return last_published_after(sequence);
 }
bool
MavlinkOrbSubscription::update_if_changed(void *data)
{
	bool prevpub = _published;

	if (!is_published()) {
		return false;
	}

	bool updated;

	if (orb_check(_fd, &updated)) {
		return false;
	}

	// If we didn't update and this topic did not change
	// its publication status then nothing really changed
	if (!updated && prevpub == _published) {
		return false;
	}

	return update(data);
}