From: Philippe Proulx Date: Mon, 5 Jun 2017 19:18:11 +0000 (-0400) Subject: Fix: cancel a notif. iter. finalized during its "next" method X-Git-Tag: v2.0.0-pre1~54 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=8cf27cc5e3f9c0ee7e1120ba0e0bd7f17d5a10ed Fix: cancel a notif. iter. finalized during its "next" method It is possible that the user's "next" method, somehow, cancels its own notification iterator. This can happen, for example, when the user's method removes the port on which there's the connection from which the notification iterator was created. In this case, said connection is ended, and all its notification iterators are finalized. In ensure_queue_has_notifications(), after calling the user's "next" method, if there's no error, we check if the notification iterator is finalized. If so, we return the BT_NOTIFICATION_ITERATOR_STATUS_CANCELED status directly. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- diff --git a/lib/graph/iterator.c b/lib/graph/iterator.c index 70930bc7..07eaa1fd 100644 --- a/lib/graph/iterator.c +++ b/lib/graph/iterator.c @@ -1550,6 +1550,32 @@ 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) { + /* + * The user's "next" method, somehow, cancelled + * its own notification iterator. This can + * happen, for example, when the user's method + * removes the port on which there's the + * connection from which the iterator was + * created. In this case, said connection is + * ended, and all its notification iterators are + * finalized. + * + * Only bt_put() the returned notification if + * the status is + * BT_NOTIFICATION_ITERATOR_STATUS_OK because + * otherwise this field could be garbage. + */ + if (next_return.status == + BT_NOTIFICATION_ITERATOR_STATUS_OK) { + bt_put(next_return.notification); + } + + status = BT_NOTIFICATION_ITERATOR_STATUS_CANCELED; + goto end; + } + switch (next_return.status) { case BT_NOTIFICATION_ITERATOR_STATUS_END: ret = handle_end(iterator);