From: Philippe Proulx Date: Wed, 24 May 2017 00:45:08 +0000 (-0400) Subject: ctf plugin: add bt_ctf_notif_iter_get_packet_header_context_fields() X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=87187cbfcf0ff2101a05e58d9043ffa86108f431;p=deliverable%2Fbabeltrace.git ctf plugin: add bt_ctf_notif_iter_get_packet_header_context_fields() The new bt_ctf_notif_iter_get_packet_header_context_fields() function returns the packet header and context fields using the usual medium operation mechanism without ever creating packet of event objects, therefore not requiring a stream object to exist. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- diff --git a/plugins/ctf/common/notif-iter/notif-iter.c b/plugins/ctf/common/notif-iter/notif-iter.c index bc20f8814..acb349380 100644 --- a/plugins/ctf/common/notif-iter/notif-iter.c +++ b/plugins/ctf/common/notif-iter/notif-iter.c @@ -2447,3 +2447,72 @@ enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_next_notification( end: return status; } + +BT_HIDDEN +enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_packet_header_context_fields( + struct bt_ctf_notif_iter *notit, + struct bt_ctf_field **packet_header_field, + struct bt_ctf_field **packet_context_field) +{ + enum bt_ctf_notif_iter_status status = BT_CTF_NOTIF_ITER_STATUS_OK; + + assert(notit); + + if (notit->state == STATE_EMIT_NOTIF_NEW_PACKET) { + /* We're already there */ + goto set_fields; + } + + while (true) { + status = handle_state(notit); + if (status == BT_CTF_NOTIF_ITER_STATUS_AGAIN) { + PDBG("Medium operation reported \"try again later\""); + goto end; + } + if (status != BT_CTF_NOTIF_ITER_STATUS_OK) { + if (status == BT_CTF_NOTIF_ITER_STATUS_EOF) { + PDBG("Medium operation reported end of stream\n"); + } else { + PERR("Failed to handle state:\n"); + PERR("\tState: %d\n", notit->state); + } + goto end; + } + + switch (notit->state) { + case STATE_EMIT_NOTIF_NEW_PACKET: + /* + * Packet header and context fields are + * potentially decoded (or they don't exist). + */ + goto set_fields; + case STATE_INIT: + case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN: + case STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE: + case STATE_AFTER_TRACE_PACKET_HEADER: + case STATE_DSCOPE_STREAM_PACKET_CONTEXT_BEGIN: + case STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE: + case STATE_AFTER_STREAM_PACKET_CONTEXT: + /* Non-emitting state: continue */ + break; + default: + /* + * We should never get past the + * STATE_EMIT_NOTIF_NEW_PACKET state. + */ + assert(false); + } + } + +set_fields: + if (packet_header_field) { + *packet_header_field = bt_get(notit->dscopes.trace_packet_header); + } + + if (packet_context_field) { + *packet_context_field = bt_get(notit->dscopes.stream_packet_context); + } + +end: + return status; +} diff --git a/plugins/ctf/common/notif-iter/notif-iter.h b/plugins/ctf/common/notif-iter/notif-iter.h index 476e7d7a9..23277754a 100644 --- a/plugins/ctf/common/notif-iter/notif-iter.h +++ b/plugins/ctf/common/notif-iter/notif-iter.h @@ -284,4 +284,22 @@ enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_next_notification( struct bt_clock_class_priority_map *cc_prio_map, struct bt_notification **notification); +/** + * Returns the first packet header and context fields. This function + * never needs to call the `get_stream()` medium operation because + * it does not create packet or event objects. + * + * @param notif_iter CTF notification iterator + * @param packet_header_field Packet header field (\c NULL if there's + * no packet header field) + * @param packet_context_field Packet context field (\c NULL if there's + * no packet context field) + * @returns One of #bt_ctf_notif_iter_status values + */ +BT_HIDDEN +enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_packet_header_context_fields( + struct bt_ctf_notif_iter *notit, + struct bt_ctf_field **packet_header_field, + struct bt_ctf_field **packet_context_field); + #endif /* CTF_NOTIF_ITER_H */