8.4.2 Loaning and Returning Data and SampleInfo Sequences

8.4.2.1 C, Traditional C++, Java and .NET

The read() and take() operations (and their variations) return information to your application in two sequences:

These sequences are parameters that are passed by your code into the read() and take() operations. If you use empty sequences (sequences that are initialized but have a maximum length of 0), Connext DDS will fill those sequences with memory directly loaned from the receive queue itself. There is no copying of the data or of SampleInfo when the contents of the sequences are loaned. This is certainly the most efficient way for your code to retrieve the data.

However when you do so, your code must return the loaned sequences back to Connext DDS so that they can be reused by the receive queue. If your code does not return the loan by calling the FooDataReader’s return_loan() method, then Connext DDS will eventually run out of memory to store DDS data samples received from the network for that DataReader. See Figure 8.21: Using Loaned Sequences in read() and take() for an example of borrowing and returning loaned sequences.

DDS_ReturnCode_t return_loan(
    FooSeq &received_data, DDS_SampleInfoSeq &info_seq);

Figure 8.21: Using Loaned Sequences in read() and take()

// In C++ and Java, sequences are automatically initialized
// to be empty
FooSeq data_seq;1 For the C API, you must use the FooSeq_initialize() and DDS_SampleInfoSeq_initialize() operations or the
macro DDS_SEQUENCE_INITIALIZER to initialize the FooSeq and DDS_SampleInfoSeq to be empty. For example,
DDS_SampleInfoSeq infoSeq;
DDS_SampleInfoSeq_initialize(&infoSeq);
or
FooSeq fooSeq = DDS_SEQUENCE_INITIALIZER;
DDS_SampleInfoSeq info_seq;
DDS_ReturnCode_t retcode;
...
// with empty sequences, a take() or read() will return loaned
// sequence elements
retcode = Foo_reader->take(data_seq, info_seq,
	DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE,
	DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);
	... // process the returned data
// must return the loaned sequences when done processing
Foo_reader->return_loan(data_seq, info_seq);
...

If your code provides its own sequences to the read/take operations, then Connext DDS will copy the data from the receive queue. In that case, you do not have to call return_loan() when you are finished with the data. However, you must make sure the following is true, or the read/take operation will fail with a return code of DDS_RETCODE_PRECONDITION_NOT_MET:

8.4.2.2 Modern C++

The read() and take() operations (and their variations) return LoanedSamples, an iterable collection of loaned, read-only samples each containing the actual data and meta-information about the sample. A LoanedSamples collection automatically returns the loan to the middleware in its destructor. You can also explicitly call LoanedSamples::return_loan().

Figure 8.22: Using LoanedSamples to read data

dds::sub::LoanedSamples<Foo> samples = reader.take();
for (auto sample : samples) { // process the data
    if (sample.info().valid()) {
        std::cout << sample.data() << std::endl;
    }
}

© 2020 RTI