From 8cf27cc5e3f9c0ee7e1120ba0e0bd7f17d5a10ed Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Mon, 5 Jun 2017 15:18:11 -0400 Subject: [PATCH] Fix: cancel a notif. iter. finalized during its "next" method MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- lib/graph/iterator.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) 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); -- 2.34.1