*/
#define _LGPL_SOURCE
-#include <assert.h>
#include <poll.h>
#include <pthread.h>
#include <stdlib.h>
int lttng_kconsumer_sample_snapshot_positions(
struct lttng_consumer_stream *stream)
{
- assert(stream);
+ LTTNG_ASSERT(stream);
return kernctl_snapshot_sample_positions(stream->wait_fd);
}
*/
pthread_mutex_lock(&stream->lock);
- assert(channel->trace_chunk);
+ LTTNG_ASSERT(channel->trace_chunk);
if (!lttng_trace_chunk_get(channel->trace_chunk)) {
/*
* Can't happen barring an internal error as the channel
ret = -1;
goto end_unlock;
}
- assert(!stream->trace_chunk);
+ LTTNG_ASSERT(!stream->trace_chunk);
stream->trace_chunk = channel->trace_chunk;
/*
ssize_t ret_read;
struct lttng_consumer_stream *metadata_stream;
- assert(ctx);
+ LTTNG_ASSERT(ctx);
DBG("Kernel consumer snapshot metadata with key %" PRIu64 " at path %s",
key, path);
rcu_read_lock();
metadata_stream = metadata_channel->metadata_stream;
- assert(metadata_stream);
+ LTTNG_ASSERT(metadata_stream);
pthread_mutex_lock(&metadata_stream->lock);
- assert(metadata_channel->trace_chunk);
- assert(metadata_stream->trace_chunk);
+ LTTNG_ASSERT(metadata_channel->trace_chunk);
+ LTTNG_ASSERT(metadata_stream->trace_chunk);
/* Flag once that we have a valid relayd for the stream. */
if (relayd_id != (uint64_t) -1ULL) {
ret_read = lttng_consumer_read_subbuffer(metadata_stream, ctx, true);
if (ret_read < 0) {
- if (ret_read != -EAGAIN) {
- ERR("Kernel snapshot reading metadata subbuffer (ret: %zd)",
- ret_read);
- ret = ret_read;
- goto error_snapshot;
- }
- /* ret_read is negative at this point so we will exit the loop. */
- continue;
+ ERR("Kernel snapshot reading metadata subbuffer (ret: %zd)",
+ ret_read);
+ ret = ret_read;
+ goto error_snapshot;
}
- } while (ret_read >= 0);
+ } while (ret_read > 0);
if (use_relayd) {
close_relayd_stream(metadata_stream);
health_code_update();
/* Deprecated command */
- assert(msg.cmd_type != LTTNG_CONSUMER_STOP);
+ LTTNG_ASSERT(msg.cmd_type != LTTNG_CONSUMER_STOP);
health_code_update();
new_channel->type = msg.u.channel.type;
break;
default:
- assert(0);
+ abort();
goto end_nosignal;
};
* This command should ONLY be issued for channel with streams set in
* no monitor mode.
*/
- assert(!channel->monitor);
+ LTTNG_ASSERT(!channel->monitor);
/*
* The refcount should ALWAYS be 0 in the case of a channel in no
* monitor mode.
*/
- assert(!uatomic_sub_return(&channel->refcount, 1));
+ LTTNG_ASSERT(!uatomic_sub_return(&channel->refcount, 1));
consumer_del_channel(channel);
end_destroy_channel:
int ret;
enum sync_metadata_status status;
- assert(metadata);
+ LTTNG_ASSERT(metadata);
ret = kernctl_buffer_flush(metadata->wait_fd);
if (ret < 0) {
}
static
-int get_subbuffer_common(struct lttng_consumer_stream *stream,
+enum get_next_subbuffer_status get_subbuffer_common(
+ struct lttng_consumer_stream *stream,
struct stream_subbuffer *subbuffer)
{
int ret;
+ enum get_next_subbuffer_status status;
ret = kernctl_get_next_subbuf(stream->wait_fd);
- 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 = stream->read_subbuffer_ops.extract_subbuffer_info(
- stream, subbuffer);
+ stream, subbuffer);
+ if (ret) {
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
+ }
end:
- return ret;
+ return status;
}
static
-int get_next_subbuffer_splice(struct lttng_consumer_stream *stream,
+enum get_next_subbuffer_status get_next_subbuffer_splice(
+ struct lttng_consumer_stream *stream,
struct stream_subbuffer *subbuffer)
{
- int ret;
+ const enum get_next_subbuffer_status status =
+ get_subbuffer_common(stream, subbuffer);
- ret = get_subbuffer_common(stream, subbuffer);
- if (ret) {
+ if (status != GET_NEXT_SUBBUFFER_STATUS_OK) {
goto end;
}
subbuffer->buffer.fd = stream->wait_fd;
end:
- return ret;
+ return status;
}
static
-int get_next_subbuffer_mmap(struct lttng_consumer_stream *stream,
+enum get_next_subbuffer_status get_next_subbuffer_mmap(
+ struct lttng_consumer_stream *stream,
struct stream_subbuffer *subbuffer)
{
int ret;
+ enum get_next_subbuffer_status status;
const char *addr;
- ret = get_subbuffer_common(stream, subbuffer);
- if (ret) {
+ status = get_subbuffer_common(stream, subbuffer);
+ if (status != GET_NEXT_SUBBUFFER_STATUS_OK) {
goto end;
}
ret = get_current_subbuf_addr(stream, &addr);
if (ret) {
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
goto end;
}
subbuffer->buffer.buffer = lttng_buffer_view_init(
addr, 0, subbuffer->info.data.padded_subbuf_size);
end:
- return ret;
+ return status;
}
static
-int get_next_subbuffer_metadata_check(struct lttng_consumer_stream *stream,
+enum get_next_subbuffer_status get_next_subbuffer_metadata_check(struct lttng_consumer_stream *stream,
struct stream_subbuffer *subbuffer)
{
int ret;
const char *addr;
bool coherent;
+ enum get_next_subbuffer_status status;
ret = kernctl_get_next_subbuf_metadata_check(stream->wait_fd,
&coherent);
subbuffer->info.metadata.padded_subbuf_size,
coherent ? "true" : "false");
end:
- return ret;
+ /*
+ * 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.
+ */
+ 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;
+ break;
+ default:
+ status = GET_NEXT_SUBBUFFER_STATUS_ERROR;
+ break;
+ }
+
+ return status;
}
static
{
int ret;
- assert(stream);
+ LTTNG_ASSERT(stream);
/*
* Don't create anything if this is set for streaming or if there is
int err;
err = close(stream->out_fd);
- assert(!err);
+ LTTNG_ASSERT(!err);
stream->out_fd = -1;
}
error:
{
int ret;
- assert(stream);
+ LTTNG_ASSERT(stream);
if (stream->endpoint_status != CONSUMER_ENDPOINT_ACTIVE) {
ret = 0;
if (ret == 0) {
/* There is still data so let's put back this subbuffer. */
ret = kernctl_put_subbuf(stream->wait_fd);
- assert(ret == 0);
+ LTTNG_ASSERT(ret == 0);
ret = 1; /* Data is pending */
goto end;
}