X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fiterator.c;h=77093217cd2e8a979b5220cffc0a7492f88464c6;hb=8f0a0314c60c7c0de9fd793aede7a879b9736928;hp=540d5e9bcf04b6ba46ca99c2a66db9ec7e31ec74;hpb=4fd5ac4b22481d3c7e3f471cdc34ccfdcea4c781;p=babeltrace.git diff --git a/lib/iterator.c b/lib/iterator.c index 540d5e9b..77093217 100644 --- a/lib/iterator.c +++ b/lib/iterator.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -72,6 +73,7 @@ static int stream_read_event(struct ctf_file_stream *sin) fprintf(stderr, "[error] Reading event failed.\n"); return ret; } + return 0; } @@ -142,6 +144,10 @@ static int seek_file_stream_by_timestamp(struct ctf_file_stream *cfs, continue; stream_pos->packet_seek(&stream_pos->parent, i, SEEK_SET); + ret = bt_packet_seek_get_error(); + if (ret < 0) { + return EOF; + } do { ret = stream_read_event(cfs); } while (cfs->parent.real_timestamp < timestamp && ret == 0); @@ -170,6 +176,16 @@ static int seek_ctf_trace_by_timestamp(struct ctf_trace *tin, { int i, j, ret; int found = 0; + struct bt_trace_descriptor *td = &tin->parent; + + if (td->interval_set) { + /* + * If this trace has an interval selected, don't allow seeks + * before the selected interval. We seek to the start of the + * interval, thereby presenting a shorter "virtual" trace. + */ + timestamp = max(timestamp, td->interval_real.timestamp_begin); + } /* for each stream_class */ for (i = 0; i < tin->streams->len; i++) { @@ -231,6 +247,10 @@ static int find_max_timestamp_ctf_file_stream(struct ctf_file_stream *cfs, */ for (i = stream_pos->packet_index->len - 1; i >= 0; i--) { stream_pos->packet_seek(&stream_pos->parent, i, SEEK_SET); + ret = bt_packet_seek_get_error(); + if (ret < 0) { + return EOF; + } count = 0; /* read each event until we reach the end of the stream */ do { @@ -615,14 +635,11 @@ error: return NULL; } -struct bt_iter_pos *bt_iter_create_time_pos(struct bt_iter *iter, +struct bt_iter_pos *bt_iter_create_time_pos(struct bt_iter *unused, uint64_t timestamp) { struct bt_iter_pos *pos; - if (!iter) - return NULL; - pos = g_new0(struct bt_iter_pos, 1); pos->type = BT_SEEK_TIME; pos->u.seek_time = timestamp; @@ -751,6 +768,9 @@ int bt_iter_init(struct bt_iter *iter, ctx->current_iterator = iter; if (begin_pos && begin_pos->type != BT_SEEK_BEGIN) { ret = bt_iter_set_pos(iter, begin_pos); + if (ret) { + goto error; + } } return ret; @@ -758,6 +778,8 @@ int bt_iter_init(struct bt_iter *iter, error: bt_heap_free(iter->stream_heap); error_heap_init: + bt_context_put(ctx); + iter->ctx = NULL; g_free(iter->stream_heap); iter->stream_heap = NULL; error_ctx: @@ -792,6 +814,7 @@ void bt_iter_fini(struct bt_iter *iter) } iter->ctx->current_iterator = NULL; bt_context_put(iter->ctx); + iter->ctx = NULL; } void bt_iter_destroy(struct bt_iter *iter) @@ -805,6 +828,7 @@ int bt_iter_next(struct bt_iter *iter) { struct ctf_file_stream *file_stream, *removed; int ret; + bool event_outside_interval = false; if (!iter) return -EINVAL; @@ -817,7 +841,13 @@ int bt_iter_next(struct bt_iter *iter) } ret = stream_read_event(file_stream); - if (ret == EOF) { + if (file_stream->pos.parent.trace && + file_stream->pos.parent.trace->interval_set) { + event_outside_interval = + file_stream->parent.real_timestamp > + file_stream->pos.parent.trace->interval_real.timestamp_end; + } + if (ret == EOF || event_outside_interval) { removed = bt_heap_remove(iter->stream_heap); assert(removed == file_stream); ret = 0; @@ -837,6 +867,10 @@ int bt_iter_next(struct bt_iter *iter) */ ret = 0; goto reinsert; + } else if (ret == -ERANGE) { + removed = bt_heap_remove(iter->stream_heap); + assert(removed == file_stream); + goto end; } else if (ret) { goto end; }