X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fiterator.c;h=3280f4a816c3a88468dfb99dd320111c24ded54d;hb=b5f5f9e1854297ddff94aa9e210dbf865e0edcfa;hp=4190e65286d914021133ea110e936a27ce51c208;hpb=1b8455b701df7ac196e35795b9ab8ef2d402058d;p=babeltrace.git diff --git a/lib/iterator.c b/lib/iterator.c index 4190e652..3280f4a8 100644 --- a/lib/iterator.c +++ b/lib/iterator.c @@ -65,6 +65,9 @@ static int stream_read_event(struct ctf_file_stream *sin) ret = sin->pos.parent.event_cb(&sin->pos.parent, &sin->parent); if (ret == EOF) return EOF; + else if (ret == EAGAIN) + /* Stream is inactive for now (live reading). */ + return EAGAIN; else if (ret) { fprintf(stderr, "[error] Reading event failed.\n"); return ret; @@ -73,16 +76,24 @@ static int stream_read_event(struct ctf_file_stream *sin) } /* - * returns true if a < b, false otherwise. + * Return true if a < b, false otherwise. + * If time stamps are exactly the same, compare by stream path. This + * ensures we get the same result between runs on the same trace + * collection on different environments. + * The result will be random for memory-mapped traces since there is no + * fixed path leading to those (they have empty path string). */ static int stream_compare(void *a, void *b) { struct ctf_file_stream *s_a = a, *s_b = b; - if (s_a->parent.real_timestamp < s_b->parent.real_timestamp) + if (s_a->parent.real_timestamp < s_b->parent.real_timestamp) { return 1; - else + } else if (likely(s_a->parent.real_timestamp > s_b->parent.real_timestamp)) { return 0; + } else { + return strcmp(s_a->parent.path, s_b->parent.path); + } } void bt_iter_free_pos(struct bt_iter_pos *iter_pos) @@ -714,7 +725,7 @@ int bt_iter_init(struct bt_iter *iter, if (ret == EOF) { ret = 0; continue; - } else if (ret) { + } else if (ret != 0 && ret != EAGAIN) { goto error; } /* Add to heap */ @@ -795,13 +806,28 @@ int bt_iter_next(struct bt_iter *iter) assert(removed == file_stream); ret = 0; goto end; + } else if (ret == EAGAIN) { + /* + * The stream is inactive for now, we just updated the timestamp_end + * to skip over this stream up to a certain point in time. + */ + goto reinsert; } else if (ret) { goto end; } + +reinsert: /* Reinsert the file stream into the heap, and rebalance. */ removed = bt_heap_replace_max(iter->stream_heap, file_stream); assert(removed == file_stream); + file_stream = bt_heap_maximum(iter->stream_heap); + if (file_stream->pos.content_size == 0) { + ret = EAGAIN; + } else { + ret = 0; + } + end: return ret; }