bt_bool is_ended;
};
-static
-void stream_destroy_listener(struct bt_stream *stream, void *data)
-{
- struct bt_notification_iterator_private_connection *iterator = data;
-
- /* Remove associated stream state */
- g_hash_table_remove(iterator->stream_states, stream);
-}
-
+BT_ASSERT_PRE_FUNC
static
void destroy_stream_state(struct stream_state *stream_state)
{
g_free(stream_state);
}
+BT_ASSERT_PRE_FUNC
static
struct stream_state *create_stream_state(struct bt_stream *stream)
{
static
void destroy_base_notification_iterator(struct bt_object *obj)
{
- struct bt_notification_iterator *iterator =
- container_of(obj, struct bt_notification_iterator, base);
-
- BT_LOGD_STR("Putting current notification.");
- bt_put(iterator->current_notification);
- g_free(iterator);
+ BT_ASSERT(obj);
+ g_free(obj);
}
static
* reference count would go from 1 to 0 again and this function
* would be called again.
*/
- obj->ref_count.count++;
- iterator = (void *) container_of(obj, struct bt_notification_iterator, base);
+ obj->ref_count++;
+ iterator = (void *) obj;
BT_LOGD("Destroying private connection notification iterator object: addr=%p",
iterator);
bt_private_connection_notification_iterator_finalize(iterator);
* listener would be called with an invalid/other
* notification iterator object.
*/
- GHashTableIter ht_iter;
- gpointer stream_gptr, stream_state_gptr;
-
- g_hash_table_iter_init(&ht_iter, iterator->stream_states);
-
- while (g_hash_table_iter_next(&ht_iter, &stream_gptr, &stream_state_gptr)) {
- BT_ASSERT(stream_gptr);
-
- BT_LOGD_STR("Removing stream's destroy listener for notification iterator.");
- bt_stream_remove_destroy_listener(
- (void *) stream_gptr, stream_destroy_listener,
- iterator);
- }
-
g_hash_table_destroy(iterator->stream_states);
}
enum bt_notification_iterator_type type,
bt_object_release_func destroy)
{
- bt_object_init(iterator, destroy);
+ bt_object_init_shared(&iterator->base, destroy);
iterator->type = type;
}
iterator->upstream_component = upstream_comp;
iterator->upstream_port = upstream_port;
iterator->connection = connection;
+ iterator->graph = bt_component_borrow_graph(upstream_comp);
iterator->state = BT_PRIVATE_CONNECTION_NOTIFICATION_ITERATOR_STATE_NON_INITIALIZED;
BT_LOGD("Created notification iterator: "
"upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
void *bt_private_connection_private_notification_iterator_get_user_data(
struct bt_private_connection_private_notification_iterator *private_iterator)
{
- struct bt_notification_iterator_private_connection *iterator =
+ struct bt_notification_iterator_private_connection *iterator = (void *)
bt_private_connection_notification_iterator_borrow_from_private(private_iterator);
BT_ASSERT_PRE_NON_NULL(private_iterator, "Notification iterator");
struct bt_private_connection_private_notification_iterator *private_iterator,
void *data)
{
- struct bt_notification_iterator_private_connection *iterator =
+ struct bt_notification_iterator_private_connection *iterator = (void *)
bt_private_connection_notification_iterator_borrow_from_private(private_iterator);
BT_ASSERT_PRE_NON_NULL(iterator, "Notification iterator");
return BT_NOTIFICATION_ITERATOR_STATUS_OK;
}
-struct bt_notification *bt_notification_iterator_get_notification(
- struct bt_notification_iterator *iterator)
+struct bt_graph *bt_private_connection_private_notification_iterator_borrow_graph(
+ struct bt_private_connection_private_notification_iterator *private_iterator)
{
+ struct bt_notification_iterator_private_connection *iterator = (void *)
+ bt_private_connection_notification_iterator_borrow_from_private(
+ private_iterator);
+
BT_ASSERT_PRE_NON_NULL(iterator, "Notification iterator");
- return bt_get(
- bt_notification_iterator_borrow_current_notification(iterator));
+ return iterator->graph;
}
BT_ASSERT_PRE_FUNC
return ret;
}
-static
enum bt_notification_iterator_status
-bt_priv_conn_private_notification_iterator_next(
- struct bt_notification_iterator_private_connection *iterator)
+bt_private_connection_notification_iterator_next(
+ struct bt_notification_iterator *user_iterator,
+ struct bt_notification **user_notif)
{
+ struct bt_notification_iterator_private_connection *iterator =
+ (void *) user_iterator;
struct bt_private_connection_private_notification_iterator *priv_iterator =
bt_private_connection_private_notification_iterator_from_notification_iterator(iterator);
bt_component_class_notification_iterator_next_method next_method = NULL;
enum bt_notification_iterator_status status =
BT_NOTIFICATION_ITERATOR_STATUS_OK;
- BT_ASSERT(iterator);
- BT_LIB_LOGD("Getting next notification iterator's notification: %!+i",
+ BT_ASSERT_PRE_NON_NULL(user_iterator, "Notification iterator");
+ BT_ASSERT_PRE_NON_NULL(user_notif, "Notification");
+ BT_ASSERT_PRE(user_iterator->type ==
+ BT_NOTIFICATION_ITERATOR_TYPE_PRIVATE_CONNECTION,
+ "Notification iterator was not created from a private connection: "
+ "%!+i", iterator);
+ BT_LIB_LOGD("Getting next private connection notification iterator's notification: %!+i",
iterator);
BT_ASSERT_PRE(iterator->state ==
BT_PRIVATE_CONNECTION_NOTIFICATION_ITERATOR_STATE_ACTIVE,
"Notification is invalid at this point: "
"%![notif-iter-]+i, %![notif-]+n",
iterator, next_return.notification);
- bt_notification_iterator_replace_current_notification(
- (void *) iterator, next_return.notification);
- bt_put(next_return.notification);
+ *user_notif = next_return.notification;
break;
default:
/* Unknown non-error status */
}
enum bt_notification_iterator_status
-bt_notification_iterator_next(struct bt_notification_iterator *iterator)
+bt_output_port_notification_iterator_next(
+ struct bt_notification_iterator *iterator,
+ struct bt_notification **user_notif)
{
enum bt_notification_iterator_status status;
+ struct bt_notification_iterator_output_port *out_port_iter =
+ (void *) iterator;
+ enum bt_graph_status graph_status;
BT_ASSERT_PRE_NON_NULL(iterator, "Notification iterator");
- BT_LOGD("Notification iterator's \"next\": iter-addr=%p", iterator);
- BT_ASSERT(iterator->type == BT_NOTIFICATION_ITERATOR_TYPE_PRIVATE_CONNECTION ||
- iterator->type == BT_NOTIFICATION_ITERATOR_TYPE_OUTPUT_PORT);
-
- switch (iterator->type) {
- case BT_NOTIFICATION_ITERATOR_TYPE_PRIVATE_CONNECTION:
- {
- struct bt_notification_iterator_private_connection *priv_conn_iter =
- (void *) iterator;
-
- /*
- * Make sure that the iterator's queue contains at least
- * one notification.
- */
- status = bt_priv_conn_private_notification_iterator_next(
- priv_conn_iter);
+ BT_ASSERT_PRE_NON_NULL(user_notif, "Notification");
+ BT_ASSERT_PRE(iterator->type ==
+ BT_NOTIFICATION_ITERATOR_TYPE_OUTPUT_PORT,
+ "Notification iterator was not created from an output port: "
+ "%!+i", iterator);
+ BT_LIB_LOGD("Getting next output port notification iterator's notification: %!+i",
+ iterator);
+ graph_status = bt_graph_consume_sink_no_check(
+ out_port_iter->graph, out_port_iter->colander);
+ switch (graph_status) {
+ case BT_GRAPH_STATUS_CANCELED:
+ BT_ASSERT(!out_port_iter->notif);
+ status = BT_NOTIFICATION_ITERATOR_STATUS_CANCELED;
break;
- }
- case BT_NOTIFICATION_ITERATOR_TYPE_OUTPUT_PORT:
- {
- struct bt_notification_iterator_output_port *out_port_iter =
- (void *) iterator;
-
- /*
- * Keep current notification in case there's an error:
- * restore this notification so that the current
- * notification is not changed from the user's point of
- * view.
- */
- struct bt_notification *old_notif =
- bt_get(bt_notification_iterator_borrow_current_notification(iterator));
- enum bt_graph_status graph_status;
-
- /*
- * Put current notification since it's possibly
- * about to be replaced by a new one by the
- * colander sink.
- */
- bt_notification_iterator_replace_current_notification(
- iterator, NULL);
- graph_status = bt_graph_consume_sink_no_check(
- out_port_iter->graph, out_port_iter->colander);
- switch (graph_status) {
- case BT_GRAPH_STATUS_CANCELED:
- status = BT_NOTIFICATION_ITERATOR_STATUS_CANCELED;
- break;
- case BT_GRAPH_STATUS_AGAIN:
- status = BT_NOTIFICATION_ITERATOR_STATUS_AGAIN;
- break;
- case BT_GRAPH_STATUS_END:
- status = BT_NOTIFICATION_ITERATOR_STATUS_END;
- break;
- case BT_GRAPH_STATUS_NOMEM:
- status = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
- break;
- case BT_GRAPH_STATUS_OK:
- status = BT_NOTIFICATION_ITERATOR_STATUS_OK;
- BT_ASSERT(bt_notification_iterator_borrow_current_notification(iterator));
- break;
- default:
- /* Other errors */
- status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
- }
-
- if (status != BT_NOTIFICATION_ITERATOR_STATUS_OK) {
- /* Error/exception: restore old notification */
- bt_notification_iterator_replace_current_notification(
- iterator, old_notif);
- }
-
- bt_put(old_notif);
+ case BT_GRAPH_STATUS_AGAIN:
+ BT_ASSERT(!out_port_iter->notif);
+ status = BT_NOTIFICATION_ITERATOR_STATUS_AGAIN;
+ break;
+ case BT_GRAPH_STATUS_END:
+ BT_ASSERT(!out_port_iter->notif);
+ status = BT_NOTIFICATION_ITERATOR_STATUS_END;
+ break;
+ case BT_GRAPH_STATUS_NOMEM:
+ BT_ASSERT(!out_port_iter->notif);
+ status = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
+ break;
+ case BT_GRAPH_STATUS_OK:
+ BT_ASSERT(out_port_iter->notif);
+ status = BT_NOTIFICATION_ITERATOR_STATUS_OK;
+ *user_notif = out_port_iter->notif;
+ out_port_iter->notif = NULL;
break;
- }
default:
- abort();
+ /* Other errors */
+ status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
}
return status;
BT_LOGD("Destroying output port notification iterator object: addr=%p",
iterator);
+ BT_ASSERT(!iterator->notif);
BT_LOGD_STR("Putting graph.");
bt_put(iterator->graph);
- BT_LOGD_STR("Putting output port.");
- bt_put(iterator->output_port);
BT_LOGD_STR("Putting colander sink component.");
bt_put(iterator->colander);
destroy_base_notification_iterator(obj);
struct bt_port *output_port,
const char *colander_component_name)
{
- struct bt_notification_iterator *iterator_base = NULL;
struct bt_notification_iterator_output_port *iterator = NULL;
struct bt_component_class *colander_comp_cls = NULL;
struct bt_component *output_port_comp = NULL;
}
BT_MOVE(iterator->graph, graph);
- iterator_base = (void *) iterator;
colander_comp_name =
colander_component_name ? colander_component_name : "colander";
- colander_data.notification = &iterator_base->current_notification;
+ colander_data.notification = &iterator->notif;
graph_status = bt_graph_add_component_with_init_method_data(
iterator->graph, colander_comp_cls, colander_comp_name,
NULL, &colander_data, &iterator->colander);
* nonconsumable forever so that only this notification iterator
* can consume (thanks to bt_graph_consume_sink_no_check()).
* This avoids leaking the notification created by the colander
- * sink and moved to the base notification iterator's current
- * notification member.
+ * sink and moved to the notification iterator's notification
+ * member.
*/
bt_graph_set_can_consume(iterator->graph, BT_FALSE);
goto end;
}
struct bt_notification_iterator *
-bt_private_connection_notification_iterator_from_private(
+bt_private_connection_notification_iterator_borrow_from_private(
struct bt_private_connection_private_notification_iterator *private_notification_iterator)
{
- return bt_get(
- bt_private_connection_notification_iterator_borrow_from_private(
- private_notification_iterator));
+ return (void *) private_notification_iterator;
}