return ret;
}
-static int get_next_subbuffer(struct lttng_consumer_stream *stream,
+static enum get_next_subbuffer_status get_next_subbuffer(
+ struct lttng_consumer_stream *stream,
struct stream_subbuffer *subbuffer)
{
int ret;
+ enum get_next_subbuffer_status status;
ret = lttng_ust_ctl_get_next_subbuf(stream->ustream);
- if (ret) {
+ switch (ret) {
+ case 0:
+ status = GET_NEXT_SUBBUFFER_STATUS_OK;
+ break;
+ case -ENODATA:
+ case -EAGAIN:
+ /*
+ * The caller only expects -ENODATA when there is no data to
+ * read, but the kernel tracer returns -EAGAIN when there is
+ * currently no data for a non-finalized stream, and -ENODATA
+ * when there is no data for a finalized stream. Those can be
+ * combined into a -ENODATA return value.
+ */
+ status = GET_NEXT_SUBBUFFER_STATUS_NO_DATA;
+ goto end;
+ default:
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
}
ret = get_next_subbuffer_common(stream, subbuffer);
if (ret) {
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
}
end:
- return ret;
+ return status;
}
-static int get_next_subbuffer_metadata(struct lttng_consumer_stream *stream,
+static enum get_next_subbuffer_status get_next_subbuffer_metadata(
+ struct lttng_consumer_stream *stream,
struct stream_subbuffer *subbuffer)
{
int ret;
bool coherent;
bool buffer_empty;
unsigned long consumed_pos, produced_pos;
+ enum get_next_subbuffer_status status;
do {
ret = lttng_ust_ctl_get_next_subbuf(stream->ustream);
got_subbuffer = false;
if (ret != -EAGAIN) {
/* Fatal error. */
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
}
}
if (!got_subbuffer) {
ret = commit_one_metadata_packet(stream);
if (ret < 0 && ret != -ENOBUFS) {
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
} else if (ret == 0) {
/* Not an error, the cache is empty. */
cache_empty = true;
- ret = -ENODATA;
+ status = GET_NEXT_SUBBUFFER_STATUS_NO_DATA;
goto end;
} else {
cache_empty = false;
/* Populate sub-buffer infos and view. */
ret = get_next_subbuffer_common(stream, subbuffer);
if (ret) {
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
}
* pushed the consumption position yet (on put_next).
*/
PERROR("Failed to take a snapshot of metadata buffer positions");
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
}
ret = lttng_ustconsumer_get_consumed_snapshot(stream, &consumed_pos);
if (ret) {
PERROR("Failed to get metadata consumed position");
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
}
ret = lttng_ustconsumer_get_produced_snapshot(stream, &produced_pos);
if (ret) {
PERROR("Failed to get metadata produced position");
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
}
coherent = got_subbuffer && cache_empty && buffer_empty;
LTTNG_OPTIONAL_SET(&subbuffer->info.metadata.coherent, coherent);
+ status = GET_NEXT_SUBBUFFER_STATUS_OK;
end:
- return ret;
+ return status;
}
static int put_next_subbuffer(struct lttng_consumer_stream *stream,