#include <glib.h>
#include <inttypes.h>
+#include <stdbool.h>
#include <unistd.h>
#include "common/assert.h"
BT_COMP_LOGD("Destroy lttng live session");
if (session->id != -1ULL) {
if (lttng_live_detach_session(session)) {
- if (session->lttng_live_msg_iter &&
- !lttng_live_graph_is_canceled(
- session->lttng_live_msg_iter)) {
+ if (!lttng_live_graph_is_canceled(
+ session->lttng_live_msg_iter)) {
/* Old relayd cannot detach sessions. */
BT_COMP_LOGD("Unable to detach lttng live session %" PRIu64,
session->id);
{
enum lttng_live_iterator_status status;
uint64_t trace_idx;
- int ret = 0;
if (!session->attached) {
- ret = lttng_live_attach_session(session);
- if (ret) {
- if (lttng_live_msg_iter && lttng_live_graph_is_canceled(
- lttng_live_msg_iter)) {
+ enum lttng_live_attach_session_status attach_status =
+ lttng_live_attach_session(session);
+ if (attach_status != LTTNG_LIVE_ATTACH_SESSION_STATUS_OK) {
+ if (lttng_live_graph_is_canceled(lttng_live_msg_iter)) {
status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
} else {
status = LTTNG_LIVE_ITERATOR_STATUS_ERROR;
status != LTTNG_LIVE_ITERATOR_STATUS_END) {
goto end;
}
- for (trace_idx = 0; trace_idx < session->traces->len; trace_idx++) {
+ trace_idx = 0;
+ while (trace_idx < session->traces->len) {
struct lttng_live_trace *trace =
g_ptr_array_index(session->traces, trace_idx);
status = lttng_live_metadata_update(trace);
- if (status != LTTNG_LIVE_ITERATOR_STATUS_OK &&
- status != LTTNG_LIVE_ITERATOR_STATUS_END) {
+ switch (status) {
+ case LTTNG_LIVE_ITERATOR_STATUS_OK:
+ trace_idx++;
+ break;
+ case LTTNG_LIVE_ITERATOR_STATUS_END:
+ /*
+ * The trace has ended. Remove it of the array an
+ * continue the iteration.
+ * We can remove the trace safely when using the
+ * g_ptr_array_remove_index_fast because it replaces
+ * the element at trace_idx with the array's last
+ * element. trace_idx is not incremented because of
+ * that.
+ */
+ (void) g_ptr_array_remove_index_fast(session->traces,
+ trace_idx);
+ break;
+ default:
goto end;
}
}
g_ptr_array_index(live_trace->stream_iterators,
stream_iter_idx);
- /*
- * Since we may remove elements from the GPtrArray as we
- * iterate over it, it's possible to see the same element more
- * than once.
- */
- if (stream_iter == youngest_candidate_stream_iter) {
- stream_iter_idx++;
- continue;
- }
-
/*
* Find if there is are now current message for this stream
* iterator get it.
stream_iter_idx++;
} else {
/*
- * The live stream iterator is ENDed. We remove that
- * iterator from the list and we restart the iteration
- * at the beginning of the live stream iterator array
- * to because the removal will shuffle the array.
+ * The live stream iterator has ended. That
+ * iterator is removed from the array, but
+ * there is no need to increment
+ * stream_iter_idx as
+ * g_ptr_array_remove_index_fast replaces the
+ * removed element with the array's last
+ * element.
*/
- g_ptr_array_remove_index_fast(live_trace->stream_iterators,
+ g_ptr_array_remove_index_fast(
+ live_trace->stream_iterators,
stream_iter_idx);
- stream_iter_idx = 0;
}
}
BT_ASSERT_DBG(lttng_live_msg_iter->sessions);
session_idx = 0;
- /*
- * Use a while loop instead of a for loop so we can restart the
- * iteration if we remove an element. We can safely call
- * next_stream_iterator_for_session() multiple times on the
- * same session as we only fetch a new message if there is no
- * current next message for each live stream iterator.
- * If all live stream iterator of that session already have a
- * current next message, the function will simply exit return
- * the same candidate live stream iterator every time.
- */
while (session_idx < lttng_live_msg_iter->sessions->len) {
struct lttng_live_session *session =
g_ptr_array_index(lttng_live_msg_iter->sessions,
if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) {
if (session->closed && session->traces->len == 0) {
/*
- * Remove the session from the list and restart the
- * iteration at the beginning of the array since the
- * removal shuffle the elements of the array.
+ * Remove the session from the list.
+ * session_idx is not modified since
+ * g_ptr_array_remove_index_fast
+ * replaces the the removed element with
+ * the array's last element.
*/
g_ptr_array_remove_index_fast(
lttng_live_msg_iter->sessions,
session_idx);
- session_idx = 0;
} else {
session_idx++;
}