Fix: do not allow a notif. iter. to call the user's "next" method once finalized
[babeltrace.git] / lib / graph / iterator.c
index 2428c72b68d4296433b6c201e416b0449d450619..70930bc75c1c68a54a3af5249a2d5dbb8683a22e 100644 (file)
@@ -50,6 +50,7 @@
 #include <babeltrace/graph/port.h>
 #include <babeltrace/types.h>
 #include <stdint.h>
+#include <stdlib.h>
 
 struct stream_state {
        struct bt_ctf_stream *stream; /* owned by this */
@@ -149,7 +150,7 @@ void destroy_action(struct action *action)
        case ACTION_TYPE_SET_STREAM_STATE_IS_ENDED:
                break;
        default:
-               assert(BT_FALSE);
+               abort();
        }
 }
 
@@ -261,7 +262,7 @@ void apply_actions(struct bt_notification_iterator *iterator)
                                action->payload.set_stream_state_cur_packet.packet);
                        break;
                default:
-                       assert(BT_FALSE);
+                       abort();
                }
        }
 
@@ -428,7 +429,7 @@ void bt_notification_iterator_finalize(
        }
        default:
                /* Unreachable */
-               assert(0);
+               abort();
        }
 
        if (finalize_method) {
@@ -664,7 +665,7 @@ bt_notification_iterator_notif_type_from_notif_type(
                iter_notif_type = BT_NOTIFICATION_ITERATOR_NOTIF_TYPE_PACKET_END;
                break;
        default:
-               assert(BT_FALSE);
+               abort();
        }
 
        return iter_notif_type;
@@ -1473,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;
@@ -1521,8 +1530,7 @@ enum bt_notification_iterator_status ensure_queue_has_notifications(
                break;
        }
        default:
-               assert(BT_FALSE);
-               break;
+               abort();
        }
 
        /*
@@ -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",
@@ -1596,7 +1596,7 @@ enum bt_notification_iterator_status ensure_queue_has_notifications(
                        break;
                default:
                        /* Unknown non-error status */
-                       assert(BT_FALSE);
+                       abort();
                }
        }
 
This page took 0.024874 seconds and 4 git commands to generate.