struct bt_notification_iterator {
struct bt_object base;
enum bt_notification_iterator_type type;
- struct bt_notification *current_notification; /* owned by this */
};
struct bt_notification_iterator_private_connection {
struct bt_notification_iterator base;
struct bt_graph *graph; /* Owned by this */
struct bt_component *colander; /* Owned by this */
- struct bt_port *output_port; /* Owned by this */
-};
-
-static inline
-struct bt_notification *bt_notification_iterator_borrow_current_notification(
- struct bt_notification_iterator *iterator)
-{
- BT_ASSERT(iterator);
- return iterator->current_notification;
-}
-static inline
-void bt_notification_iterator_replace_current_notification(
- struct bt_notification_iterator *iterator,
- struct bt_notification *notification)
-{
- BT_ASSERT(iterator);
- bt_put(iterator->current_notification);
- iterator->current_notification = bt_get(notification);
-}
+ /* Only used temporarily: should always be NULL */
+ struct bt_notification *notif;
+};
static inline
struct bt_private_connection_private_notification_iterator *
BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED = -2,
};
-extern struct bt_notification *bt_notification_iterator_borrow_notification(
- struct bt_notification_iterator *iterator);
-
-/**
- * Get current notification at iterator's position.
- *
- * This functions will <b>not</b> advance the cursor's position.
- * The returned notification's reference count is already incremented.
- *
- * @param iterator Iterator instance
- * @returns Returns a bt_notification instance
- *
- * @see bt_put()
- */
-static inline
-struct bt_notification *bt_notification_iterator_get_notification(
- struct bt_notification_iterator *iterator)
-{
- return bt_get(bt_notification_iterator_borrow_notification(iterator));
-}
-
-/**
- * Advance the iterator's position forward.
- *
- * This function can be called repeatedly to iterate through the iterator's
- * associated trace.
- *
- * @param iterator Iterator instance
- * @returns Returns a bt_notification instance
- *
- * @see bt_notification_iterator_get_notification()
- */
-extern enum bt_notification_iterator_status
-bt_notification_iterator_next(struct bt_notification_iterator *iterator);
-
#ifdef __cplusplus
}
#endif
* SOFTWARE.
*/
-/* For enum bt_notification_type */
-#include <babeltrace/graph/notification.h>
+/* For enum bt_notification_iterator_status */
+#include <babeltrace/graph/notification-iterator.h>
#ifdef __cplusplus
extern "C" {
#endif
struct bt_port;
+struct bt_notification;
struct bt_notification_iterator;
extern struct bt_notification_iterator *bt_output_port_notification_iterator_create(
struct bt_port *port, const char *colander_component_name);
+extern enum bt_notification_iterator_status
+bt_output_port_notification_iterator_next(struct bt_notification_iterator *iterator,
+ struct bt_notification **notification);
+
#ifdef __cplusplus
}
#endif
* SOFTWARE.
*/
+/* For enum bt_notification_iterator_status */
+#include <babeltrace/graph/notification-iterator.h>
+
#ifdef __cplusplus
extern "C" {
#endif
struct bt_component;
+struct bt_notification;
struct bt_notification_iterator;
extern struct bt_component *bt_private_connection_notification_iterator_get_component(
struct bt_notification_iterator *iterator);
+extern enum bt_notification_iterator_status
+bt_private_connection_notification_iterator_next(
+ struct bt_notification_iterator *iterator,
+ struct bt_notification **notification);
+
#ifdef __cplusplus
}
#endif
#include <babeltrace/graph/private-component-sink.h>
#include <babeltrace/graph/private-port.h>
#include <babeltrace/graph/private-connection.h>
+#include <babeltrace/graph/private-connection-notification-iterator.h>
#include <babeltrace/graph/private-component.h>
#include <babeltrace/graph/component-class-sink-colander-internal.h>
#include <babeltrace/assert-internal.h>
goto end;
}
- notif_iter_status = bt_notification_iterator_next(
- colander_data->notif_iter);
+ notif_iter_status = bt_private_connection_notification_iterator_next(
+ colander_data->notif_iter, ¬if);
switch (notif_iter_status) {
case BT_NOTIFICATION_ITERATOR_STATUS_CANCELED:
status = BT_COMPONENT_STATUS_OK;
goto end;
}
- notif = bt_notification_iterator_get_notification(
- colander_data->notif_iter);
BT_ASSERT(notif);
end:
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
* would be called again.
*/
obj->ref_count.count++;
- iterator = (void *) container_of(obj, struct bt_notification_iterator, base);
+ iterator = (void *) obj;
BT_LOGD("Destroying private connection notification iterator object: addr=%p",
iterator);
bt_private_connection_notification_iterator_finalize(iterator);
return iterator->graph;
}
-struct bt_notification *bt_notification_iterator_borrow_notification(
- struct bt_notification_iterator *iterator)
-{
- BT_ASSERT_PRE_NON_NULL(iterator, "Notification iterator");
- return bt_notification_iterator_borrow_current_notification(iterator);
-}
-
BT_ASSERT_PRE_FUNC
static inline
void bt_notification_borrow_packet_stream(struct bt_notification *notif,
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;
SET_TMP_PREFIX("colander-comp-");
format_component(buf_ch, false, tmp_prefix,
iter_output_port->colander);
- SET_TMP_PREFIX("output-port-");
- format_port(buf_ch, false, tmp_prefix,
- iter_output_port->output_port);
break;
}
default:
enum bt_component_status pretty_consume(struct bt_private_component *component)
{
enum bt_component_status ret;
- struct bt_notification *notification = NULL;
+ struct bt_notification *notif = NULL;
struct bt_notification_iterator *it;
struct pretty_component *pretty =
bt_private_component_get_user_data(component);
}
it = pretty->input_iterator;
- it_ret = bt_notification_iterator_next(it);
+ it_ret = bt_private_connection_notification_iterator_next(it, ¬if);
switch (it_ret) {
case BT_NOTIFICATION_ITERATOR_STATUS_END:
goto end;
}
- notification = bt_notification_iterator_borrow_notification(it);
- BT_ASSERT(notification);
- ret = handle_notification(pretty, notification);
+ BT_ASSERT(notif);
+ ret = handle_notification(pretty, notif);
end:
+ bt_put(notif);
return ret;
}
struct counter *counter;
enum bt_notification_iterator_status it_ret;
int64_t count;
+ struct bt_notification *notif = NULL;
counter = bt_private_component_get_user_data(component);
BT_ASSERT(counter);
}
/* Consume one notification */
- it_ret = bt_notification_iterator_next(counter->notif_iter);
+ it_ret = bt_private_connection_notification_iterator_next(
+ counter->notif_iter, ¬if);
if (it_ret < 0) {
ret = BT_COMPONENT_STATUS_ERROR;
goto end;
goto end;
case BT_NOTIFICATION_ITERATOR_STATUS_OK:
{
- struct bt_notification *notif =
- bt_notification_iterator_borrow_notification(
- counter->notif_iter);
-
BT_ASSERT(notif);
switch (bt_notification_get_type(notif)) {
case BT_NOTIFICATION_TYPE_EVENT:
try_print_count(counter);
end:
+ bt_put(notif);
return ret;
}
}
/* Consume one notification */
- it_ret = bt_notification_iterator_next(dummy->notif_iter);
+ it_ret = bt_private_connection_notification_iterator_next(
+ dummy->notif_iter, ¬if);
switch (it_ret) {
case BT_NOTIFICATION_ITERATOR_STATUS_ERROR:
ret = BT_COMPONENT_STATUS_ERROR;
/* Owned by this, NULL if ended */
struct bt_notification_iterator *notif_iter;
+ /* Owned by this */
+ struct bt_notification *notif;
+
/*
* This flag is true if the upstream notification iterator's
* current notification must be considered for the multiplexing
muxer_upstream_notif_iter->notif_iter,
muxer_upstream_notif_iter->is_valid);
bt_put(muxer_upstream_notif_iter->notif_iter);
+ bt_put(muxer_upstream_notif_iter->notif);
g_free(muxer_upstream_notif_iter);
}
struct muxer_upstream_notif_iter *muxer_upstream_notif_iter)
{
enum bt_notification_iterator_status status;
+ struct bt_notification *notif = NULL;
BT_LOGV("Calling upstream notification iterator's \"next\" method: "
"muxer-upstream-notif-iter-wrap-addr=%p, notif-iter-addr=%p",
muxer_upstream_notif_iter,
muxer_upstream_notif_iter->notif_iter);
- status = bt_notification_iterator_next(
- muxer_upstream_notif_iter->notif_iter);
+ status = bt_private_connection_notification_iterator_next(
+ muxer_upstream_notif_iter->notif_iter, ¬if);
BT_LOGV("Upstream notification iterator's \"next\" method returned: "
"status=%s", bt_notification_iterator_status_string(status));
*/
BT_LOGV_STR("Validated upstream notification iterator wrapper.");
muxer_upstream_notif_iter->is_valid = true;
+ BT_MOVE(muxer_upstream_notif_iter->notif, notif);
break;
case BT_NOTIFICATION_ITERATOR_STATUS_AGAIN:
/*
break;
}
+ BT_ASSERT(!notif);
return status;
}
}
BT_ASSERT(cur_muxer_upstream_notif_iter->is_valid);
- notif = bt_notification_iterator_borrow_notification(
- cur_muxer_upstream_notif_iter->notif_iter);
+ notif = cur_muxer_upstream_notif_iter->notif;
BT_ASSERT(notif);
ret = get_notif_ts_ns(muxer_comp, muxer_notif_iter, notif,
muxer_notif_iter->last_returned_ts_ns, ¬if_ts_ns);
muxer_notif_iter, muxer_upstream_notif_iter, next_return_ts);
BT_ASSERT(next_return.status == BT_NOTIFICATION_ITERATOR_STATUS_OK);
BT_ASSERT(muxer_upstream_notif_iter);
- next_return.notification = bt_notification_iterator_get_notification(
- muxer_upstream_notif_iter->notif_iter);
+ next_return.notification = bt_get(muxer_upstream_notif_iter->notif);
BT_ASSERT(next_return.notification);
/*
#include <babeltrace/graph/private-component-sink.h>
#include <babeltrace/graph/private-component.h>
#include <babeltrace/graph/private-connection.h>
+#include <babeltrace/graph/private-connection-notification-iterator.h>
#include <babeltrace/graph/private-connection-private-notification-iterator.h>
#include <babeltrace/graph/private-port.h>
#include <babeltrace/plugin/plugin.h>
static
enum bt_notification_iterator_status common_consume(
- struct bt_notification_iterator *notif_iter)
+ struct bt_notification_iterator *notif_iter,
+ bool is_output_port_notif_iter)
{
enum bt_notification_iterator_status ret;
struct bt_notification *notification = NULL;
bool do_append_test_event = true;
BT_ASSERT(notif_iter);
- ret = bt_notification_iterator_next(notif_iter);
+ if (is_output_port_notif_iter) {
+ ret = bt_output_port_notification_iterator_next(notif_iter,
+ ¬ification);
+ } else {
+ ret = bt_private_connection_notification_iterator_next(
+ notif_iter, ¬ification);
+ }
+
if (ret < 0) {
do_append_test_event = false;
goto end;
break;
}
- notification = bt_notification_iterator_get_notification(
- notif_iter);
BT_ASSERT(notification);
switch (bt_notification_get_type(notification)) {
enum bt_notification_iterator_status it_ret;
BT_ASSERT(user_data && user_data->notif_iter);
- it_ret = common_consume(user_data->notif_iter);
+ it_ret = common_consume(user_data->notif_iter, false);
if (it_ret < 0) {
ret = BT_COMPONENT_STATUS_ERROR;
/* Consume the notification iterator */
while (iter_status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
- iter_status = common_consume(notif_iter);
+ iter_status = common_consume(notif_iter, true);
}
ok(iter_status == BT_NOTIFICATION_ITERATOR_STATUS_END,
bool do_append_test_event = true;
BT_ASSERT(user_data && user_data->notif_iter);
- it_ret = bt_notification_iterator_next(user_data->notif_iter);
+ it_ret = bt_private_connection_notification_iterator_next(
+ user_data->notif_iter, ¬ification);
if (it_ret < 0) {
ret = BT_COMPONENT_STATUS_ERROR;
break;
}
- notification = bt_notification_iterator_get_notification(
- user_data->notif_iter);
BT_ASSERT(notification);
switch (bt_notification_get_type(notification)) {