From: Philippe Proulx Date: Mon, 5 Jun 2017 16:52:29 +0000 (-0400) Subject: Fix: do not allow a notif. iter. to call the user's "next" method once finalized X-Git-Tag: v2.0.0-pre1~55 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=8f9d7550c162149e4cc7baf4456aa767d0020423 Fix: do not allow a notif. iter. to call the user's "next" method once finalized Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- diff --git a/include/babeltrace/graph/notification-iterator-internal.h b/include/babeltrace/graph/notification-iterator-internal.h index 7b748e7b..f5454744 100644 --- a/include/babeltrace/graph/notification-iterator-internal.h +++ b/include/babeltrace/graph/notification-iterator-internal.h @@ -180,4 +180,22 @@ const char *bt_notification_iterator_status_string( } }; +static inline +const char *bt_notification_iterator_state_string( + enum bt_notification_iterator_state state) +{ + switch (state) { + case BT_NOTIFICATION_ITERATOR_STATE_ACTIVE: + return "BT_NOTIFICATION_ITERATOR_STATE_ACTIVE"; + case BT_NOTIFICATION_ITERATOR_STATE_ENDED: + return "BT_NOTIFICATION_ITERATOR_STATE_ENDED"; + case BT_NOTIFICATION_ITERATOR_STATE_FINALIZED: + return "BT_NOTIFICATION_ITERATOR_STATE_FINALIZED"; + case BT_NOTIFICATION_ITERATOR_STATE_FINALIZED_AND_ENDED: + return "BT_NOTIFICATION_ITERATOR_STATE_FINALIZED_AND_ENDED"; + default: + return "(unknown)"; + } +}; + #endif /* BABELTRACE_COMPONENT_NOTIFICATION_ITERATOR_INTERNAL_H */ diff --git a/lib/graph/iterator.c b/lib/graph/iterator.c index 1a295cb3..70930bc7 100644 --- a/lib/graph/iterator.c +++ b/lib/graph/iterator.c @@ -1474,17 +1474,25 @@ enum bt_notification_iterator_status ensure_queue_has_notifications( assert(iterator); BT_LOGD("Ensuring that notification iterator's queue has at least one notification: " - "iter-addr=%p, queue-size=%u", - iterator, iterator->queue->length); + "iter-addr=%p, queue-size=%u, iter-state=%s", + iterator, iterator->queue->length, + bt_notification_iterator_state_string(iterator->state)); if (iterator->queue->length > 0) { - /* We already have enough */ + /* + * We already have enough. Even if this notification + * iterator is finalized, its user can still flush its + * current queue's content by calling its "next" method + * since this content is local and has no impact on what + * used to be the iterator's upstream component. + */ BT_LOGD_STR("Queue already has at least one notification."); goto end; } switch (iterator->state) { case BT_NOTIFICATION_ITERATOR_STATE_FINALIZED_AND_ENDED: + case BT_NOTIFICATION_ITERATOR_STATE_FINALIZED: BT_LOGD_STR("Notification iterator's \"next\" called, but it is finalized."); status = BT_NOTIFICATION_ITERATOR_STATUS_CANCELED; goto end; @@ -1551,20 +1559,12 @@ enum bt_notification_iterator_status ensure_queue_has_notifications( goto end; } - if (iterator->state == BT_NOTIFICATION_ITERATOR_STATE_FINALIZED) { - iterator->state = - BT_NOTIFICATION_ITERATOR_STATE_FINALIZED_AND_ENDED; - - if (iterator->queue->length == 0) { - status = BT_NOTIFICATION_ITERATOR_STATUS_CANCELED; - } - } else { - iterator->state = - BT_NOTIFICATION_ITERATOR_STATE_ENDED; + assert(iterator->state == + BT_NOTIFICATION_ITERATOR_STATE_ACTIVE); + iterator->state = BT_NOTIFICATION_ITERATOR_STATE_ENDED; - if (iterator->queue->length == 0) { - status = BT_NOTIFICATION_ITERATOR_STATUS_END; - } + if (iterator->queue->length == 0) { + status = BT_NOTIFICATION_ITERATOR_STATUS_END; } BT_LOGD("Set new status: status=%s",