-void destroy_action(struct action *action)
-{
- assert(action);
-
- switch (action->type) {
- case ACTION_TYPE_PUSH_NOTIF:
- BT_PUT(action->payload.push_notif.notif);
- break;
- case ACTION_TYPE_MAP_PORT_TO_COMP_IN_STREAM:
- BT_PUT(action->payload.map_port_to_comp_in_stream.stream);
- BT_PUT(action->payload.map_port_to_comp_in_stream.component);
- BT_PUT(action->payload.map_port_to_comp_in_stream.port);
- break;
- case ACTION_TYPE_ADD_STREAM_STATE:
- BT_PUT(action->payload.add_stream_state.stream);
- destroy_stream_state(
- action->payload.add_stream_state.stream_state);
- action->payload.add_stream_state.stream_state = NULL;
- break;
- case ACTION_TYPE_SET_STREAM_STATE_CUR_PACKET:
- BT_PUT(action->payload.set_stream_state_cur_packet.packet);
- break;
- case ACTION_TYPE_SET_STREAM_STATE_IS_ENDED:
- break;
- default:
- abort();
- }
-}
-
-static
-void add_action(struct bt_notification_iterator *iterator,
- struct action *action)
-{
- g_array_append_val(iterator->actions, *action);
-}
-
-static
-void clear_actions(struct bt_notification_iterator *iterator)
-{
- size_t i;
-
- for (i = 0; i < iterator->actions->len; i++) {
- struct action *action = &g_array_index(iterator->actions,
- struct action, i);
-
- destroy_action(action);
- }
-
- g_array_set_size(iterator->actions, 0);
-}
-
-static inline
-const char *action_type_string(enum action_type type)
-{
- switch (type) {
- case ACTION_TYPE_PUSH_NOTIF:
- return "ACTION_TYPE_PUSH_NOTIF";
- case ACTION_TYPE_MAP_PORT_TO_COMP_IN_STREAM:
- return "ACTION_TYPE_MAP_PORT_TO_COMP_IN_STREAM";
- case ACTION_TYPE_ADD_STREAM_STATE:
- return "ACTION_TYPE_ADD_STREAM_STATE";
- case ACTION_TYPE_SET_STREAM_STATE_IS_ENDED:
- return "ACTION_TYPE_SET_STREAM_STATE_IS_ENDED";
- case ACTION_TYPE_SET_STREAM_STATE_CUR_PACKET:
- return "ACTION_TYPE_SET_STREAM_STATE_CUR_PACKET";
- default:
- return "(unknown)";
- }
-}
-
-static
-void apply_actions(struct bt_notification_iterator *iterator)
-{
- size_t i;
-
- BT_LOGV("Applying notification's iterator current actions: "
- "count=%u", iterator->actions->len);
-
- for (i = 0; i < iterator->actions->len; i++) {
- struct action *action = &g_array_index(iterator->actions,
- struct action, i);
-
- BT_LOGV("Applying action: index=%zu, type=%s",
- i, action_type_string(action->type));
-
- switch (action->type) {
- case ACTION_TYPE_PUSH_NOTIF:
- /* Move notification to queue */
- g_queue_push_head(iterator->queue,
- action->payload.push_notif.notif);
- bt_notification_freeze(
- action->payload.push_notif.notif);
- action->payload.push_notif.notif = NULL;
- break;
- case ACTION_TYPE_MAP_PORT_TO_COMP_IN_STREAM:
- bt_ctf_stream_map_component_to_port(
- action->payload.map_port_to_comp_in_stream.stream,
- action->payload.map_port_to_comp_in_stream.component,
- action->payload.map_port_to_comp_in_stream.port);
- break;
- case ACTION_TYPE_ADD_STREAM_STATE:
- /* Move stream state to hash table */
- g_hash_table_insert(iterator->stream_states,
- action->payload.add_stream_state.stream,
- action->payload.add_stream_state.stream_state);
-
- action->payload.add_stream_state.stream_state = NULL;
- break;
- case ACTION_TYPE_SET_STREAM_STATE_IS_ENDED:
- /*
- * We know that this stream is ended. We need to
- * remember this as long as the stream exists to
- * enforce that the same stream does not end
- * twice.
- *
- * Here we add a destroy listener to the stream
- * which we put after (becomes weak as the hash
- * table key). If we were the last object to own
- * this stream, the destroy listener is called
- * when we call bt_put() which removes this
- * stream state completely. This is important
- * because the memory used by this stream object
- * could be reused for another stream, and they
- * must have different states.
- */
- bt_ctf_stream_add_destroy_listener(
- action->payload.set_stream_state_is_ended.stream_state->stream,
- stream_destroy_listener, iterator);
- action->payload.set_stream_state_is_ended.stream_state->is_ended = BT_TRUE;
- BT_PUT(action->payload.set_stream_state_is_ended.stream_state->stream);
- break;
- case ACTION_TYPE_SET_STREAM_STATE_CUR_PACKET:
- /* Move packet to stream state's current packet */
- BT_MOVE(action->payload.set_stream_state_cur_packet.stream_state->cur_packet,
- action->payload.set_stream_state_cur_packet.packet);
- break;
- default:
- abort();
- }
- }
-
- clear_actions(iterator);
-}
-
-static
-struct stream_state *create_stream_state(struct bt_ctf_stream *stream)