Fix: do not allow a notif. iter. to call the user's "next" method once finalized
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 5 Jun 2017 16:52:29 +0000 (12:52 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 9 Jun 2017 21:02:58 +0000 (17:02 -0400)
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/babeltrace/graph/notification-iterator-internal.h
lib/graph/iterator.c

index 7b748e7bff10fd4c78b4181b2a5b5325eb489203..f54547442b805764d44c964b6651875869bcd868 100644 (file)
@@ -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 */
index 1a295cb3c4f1865cf92dc59267c4ffa1eeb987b1..70930bc75c1c68a54a3af5249a2d5dbb8683a22e 100644 (file)
@@ -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",
This page took 0.027021 seconds and 4 git commands to generate.