Modern C++ API - DataReader::take(T &sample, dds::sub::SampleInfo &si) not working as expected

3 posts / 0 new
Last post
Last seen: 4 years 1 month ago
Joined: 08/25/2015
Posts: 32
Modern C++ API - DataReader::take(T &sample, dds::sub::SampleInfo &si) not working as expected


One of our usecases requires the access to the SampleInfo data when retrieving data. The problem is, that DataReader::take() does not reset the SampleInfo's valid() when there is no data to read.

The documentation does not mention anything about this case (calling take() when there's no data available) but I would expect that SampleInfo::valid() returns false.

Here a small example:

dds::domain::DomainParticipant participant(0);

dds::topic::Topic<Foo> topic(participant, "Foo");

dds::pub::DataWriter<Foo> writer(dds::pub::Publisher(participant), topic);

dds::sub::DataReader<Foo> reader(dds::sub::Subscriber(participant), topic);

fprintf(stdout, "Give Reader/Writer some time ...\n");


fprintf(stdout, "Publishing data ...\n");

Foo sample;;


fprintf(stdout, "Reading the data published...\n");

int i = 0;

dds::sub::SampleInfo si;

while(true) {

 if (i++ > 10) break;;

 reader->take(sample, si);

 fprintf(stdout, "Valid: %d - id = %d\n", si.valid(),;

 if (!si.valid()) break;


And the output:

Give Reader/Writer some time ...
Publishing data ...
Reading the data published...
Valid: 1 - id = 52
Valid: 1 - id = -1

Is this the expected behaviour?



Christian Ehrlicher


Last seen: 8 months 2 weeks ago
Joined: 01/10/2013
Posts: 28

Hi Christian, 

Thanks for bringing this up. You're right, this is not the correct behavior. At the moment, that API does not provide a good way for the user ot know if there was data or not. I will file an issue to fix this in future releases. For now, a workaround could be to pass in a new SampleInfo object to each call to take() and then check if it has been updated with values. For example, you can use the SampleInfo::publication_sequence_number() and compare it against rti::core::SequenceNumber::unknown(). If there was data then this should be a valid sequence number, otherwise the value will not change from the initial unknown value. 

Also, is there a specific reason that you are using this take API? This API takes the next sample in the reader's queue one at a time, making a copy of the data into the sample that you provide to the API. There are also a number of APIs that will not make a copy of the data and instead will provide you with a loan of all of the samples in the reader's queue at the time. There is a good example of using the different read and take APIs here:

Please let me know if you have any questions. 

Last seen: 4 years 1 month ago
Joined: 08/25/2015
Posts: 32



thx for your reply. My current workaround is to use an empy SampleInfo() - object for every call and check for valid() there. Maybe remembering SampleInfo::publication_sequence_number() and check if it has changed will avoid the create/destroy of the SampleInfo object... I'll check this.

The reason why I'm using take() is that I reimplemented a very small subset of the connext request/reply functionality with the modern C++ API. And here the throuput of the request/reply does not (yet) matter because we normally handle requests which are generated by user input.