From: Jérémie Galarneau Date: Wed, 7 Sep 2016 18:56:02 +0000 (-0400) Subject: Plugins are alive! X-Git-Tag: v2.0.0-pre1~766 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=78586d8a10bfb11d34d187697ae15e9255c6ddf4 Plugins are alive! Signed-off-by: Jérémie Galarneau --- diff --git a/converter/babeltrace.c b/converter/babeltrace.c index 36db88d1..e563c0a4 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -290,9 +290,29 @@ int main(int argc, char **argv) } do { + enum bt_component_status sink_status; struct bt_notification *notification = bt_notification_iterator_get_notification(it); + + if (!notification) { + /* + * Should never happen in final code except after next + * has returned BT_NOTIFICATION_ITERATOR_STATUS_END. + * + * Right now it happens at the first event since the + * iterator is not completely initialized and we don't + * have a notification "heap" in place. + */ + continue; + } + + sink_status = bt_component_sink_handle_notification(sink, + notification); BT_PUT(notification); + if (sink_status != BT_COMPONENT_STATUS_OK) { + fprintf(stderr, "Sink component returned an error, aborting...\n"); + break; + } } while (bt_notification_iterator_next(it) == BT_NOTIFICATION_ITERATOR_STATUS_OK); /* teardown and exit */ diff --git a/formats/ctf/ir/event.c b/formats/ctf/ir/event.c index 3ea59eaa..535d7b24 100644 --- a/formats/ctf/ir/event.c +++ b/formats/ctf/ir/event.c @@ -600,6 +600,27 @@ void bt_ctf_event_destroy(struct bt_object *obj) g_free(event); } +uint64_t bt_ctf_event_get_clock_value(struct bt_ctf_event *event, + struct bt_ctf_clock *clock) +{ + uint64_t ret = -1ULL; + uint64_t *clock_value; + + if (!event || !clock) { + goto end; + } + + clock_value = g_hash_table_lookup(event->clock_values, clock); + if (!clock_value) { + goto end; + } + + ret = *clock_value; + +end: + return ret; +} + static int set_integer_field_value(struct bt_ctf_field* field, uint64_t value) { @@ -856,24 +877,3 @@ int bt_ctf_event_register_stream_clock_values(struct bt_ctf_event *event) return ret; } - -uint64_t bt_ctf_event_get_clock_value(struct bt_ctf_event *event, - struct bt_ctf_clock *clock) -{ - uint64_t ret = -1ULL; - uint64_t *clock_value; - - if (!event || !clock) { - goto end; - } - - clock_value = g_hash_table_lookup(event->clock_values, clock); - if (!clock_value) { - goto end; - } - - ret = *clock_value; - -end: - return ret; -} diff --git a/include/babeltrace/object-internal.h b/include/babeltrace/object-internal.h index 747950f7..fb37d97a 100644 --- a/include/babeltrace/object-internal.h +++ b/include/babeltrace/object-internal.h @@ -33,7 +33,7 @@ /** * All objects publicly exposed by Babeltrace APIs must contain this structure * as their first member. This allows the unification of all ref counting - * mechanism and may be used to provide more base functionality to all + * mechanisms and may be used to provide more base functionality to all * objects. */ struct bt_object { diff --git a/include/babeltrace/plugin/notification/event-internal.h b/include/babeltrace/plugin/notification/event-internal.h index f9876bd8..1f3143ff 100644 --- a/include/babeltrace/plugin/notification/event-internal.h +++ b/include/babeltrace/plugin/notification/event-internal.h @@ -4,7 +4,7 @@ /* * BabelTrace - Plug-in Event Notification internal * - * Copyright 2015 Jérémie Galarneau + * Copyright 2016 Jérémie Galarneau * * Author: Jérémie Galarneau * @@ -27,13 +27,8 @@ * SOFTWARE. */ -#include -#include -#include -#include -#include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -41,8 +36,6 @@ extern "C" { struct bt_notification_event { struct bt_notification parent; - struct bt_ctf_trace *trace; - struct bt_ctf_stream *stream; struct bt_ctf_event *event; }; diff --git a/include/babeltrace/plugin/notification/event.h b/include/babeltrace/plugin/notification/event.h index 49505d0d..d60cd564 100644 --- a/include/babeltrace/plugin/notification/event.h +++ b/include/babeltrace/plugin/notification/event.h @@ -4,7 +4,7 @@ /* * BabelTrace - Plug-in Event Notification * - * Copyright 2015 Jérémie Galarneau + * Copyright 2016 Jérémie Galarneau * * Author: Jérémie Galarneau * @@ -32,46 +32,20 @@ extern "C" { #endif struct bt_notification; -struct bt_ctf_trace; -struct bt_ctf_stream; struct bt_ctf_event; +/***BT_NOTIFICATION_TYPE_EVENT ***/ /** * Create an event notification. * - * @param trace The event's trace - * @param stream The event's stream * @param event The event * @returns An event notification instance * * @see #bt_notification_type */ extern struct bt_notification *bt_notification_event_create( - struct bt_ctf_trace *trace, struct bt_ctf_stream *stream, struct bt_ctf_event *event); -/** - * Get an event notification's associated trace. - * - * @param notification Event notification instance - * @returns A trace instance - * - * @see #bt_ctf_trace - */ -extern struct bt_ctf_trace *bt_notification_event_get_trace( - struct bt_notification *notification); - -/** - * Get an event notification's associated stream. - * - * @param notification Event notification instance - * @returns A stream instance - * - * @see #bt_ctf_stream - */ -extern struct bt_ctf_stream *bt_notification_event_get_stream( - struct bt_notification *notification); - /** * Get an event notification's event. * diff --git a/include/babeltrace/plugin/notification/notification-internal.h b/include/babeltrace/plugin/notification/notification-internal.h index 2b5b291b..77b6bf13 100644 --- a/include/babeltrace/plugin/notification/notification-internal.h +++ b/include/babeltrace/plugin/notification/notification-internal.h @@ -41,6 +41,11 @@ struct bt_notification { enum bt_notification_type type; }; +BT_HIDDEN +void bt_notification_init(struct bt_notification *notification, + enum bt_notification_type type, + bt_object_release_func release); + #ifdef __cplusplus } #endif diff --git a/include/babeltrace/plugin/notification/notification.h b/include/babeltrace/plugin/notification/notification.h index 487c737e..5557f919 100644 --- a/include/babeltrace/plugin/notification/notification.h +++ b/include/babeltrace/plugin/notification/notification.h @@ -48,11 +48,11 @@ enum bt_notification_type { /** Event delivery notification, see event.h */ BT_NOTIFICATION_TYPE_EVENT = 1, - /** New stream packet notification, see packet.h */ - BT_NOTIFICATION_TYPE_NEW_PACKET = 2, + /** Start of stream packet notification, see packet.h */ + BT_NOTIFICATION_TYPE_PACKET_START = 2, /** End of stream packet notification, see packet.h */ - BT_NOTIFICATION_TYPE_END_PACKET = 3, + BT_NOTIFICATION_TYPE_PACKET_END = 3, /** New trace notification, see model.h */ BT_NOTIFICATION_TYPE_NEW_TRACE = 4, diff --git a/include/babeltrace/plugin/notification/packet-internal.h b/include/babeltrace/plugin/notification/packet-internal.h index e69de29b..f1d1301e 100644 --- a/include/babeltrace/plugin/notification/packet-internal.h +++ b/include/babeltrace/plugin/notification/packet-internal.h @@ -0,0 +1,43 @@ +#ifndef BABELTRACE_PLUGIN_NOTIFICATION_PACKET_INTERNAL_H +#define BABELTRACE_PLUGIN_NOTIFICATION_PACKET_INTERNAL_H + +/* + * BabelTrace - Packet-related Notifications + * + * Copyright 2016 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +struct bt_notification_packet_start { + struct bt_notification parent; + struct bt_ctf_packet *packet; +}; + +struct bt_notification_packet_end { + struct bt_notification parent; + struct bt_ctf_packet *packet; +}; + +#endif /* BABELTRACE_PLUGIN_NOTIFICATION_PACKET_INTERNAL_H */ diff --git a/include/babeltrace/plugin/notification/packet.h b/include/babeltrace/plugin/notification/packet.h index 1d4a5ce7..2a8281b5 100644 --- a/include/babeltrace/plugin/notification/packet.h +++ b/include/babeltrace/plugin/notification/packet.h @@ -2,9 +2,9 @@ #define BABELTRACE_PLUGIN_NOTIFICATION_PACKET_H /* - * BabelTrace - Plug-in Packet Notifications + * BabelTrace - Plug-in Packet-related Notifications * - * Copyright 2015 Jérémie Galarneau + * Copyright 2016 Jérémie Galarneau * * Author: Jérémie Galarneau * @@ -27,10 +27,24 @@ * SOFTWARE. */ +#include + #ifdef __cplusplus extern "C" { #endif +/*** BT_NOTIFICATION_TYPE_PACKET_START ***/ +struct bt_notification *bt_notification_packet_start_create( + struct bt_ctf_packet *packet); +struct bt_ctf_packet *bt_notification_packet_start_get_packet( + struct bt_notification *notification); + +/*** BT_NOTIFICATION_TYPE_PACKET_END ***/ +struct bt_notification *bt_notification_packet_end_create( + struct bt_ctf_packet *packet); +struct bt_ctf_packet *bt_notification_packet_end_get_packet( + struct bt_notification *notification); + #ifdef __cplusplus } #endif diff --git a/include/babeltrace/ref-internal.h b/include/babeltrace/ref-internal.h index 224e9229..8578de97 100644 --- a/include/babeltrace/ref-internal.h +++ b/include/babeltrace/ref-internal.h @@ -34,7 +34,7 @@ struct bt_object; typedef void (*bt_object_release_func)(struct bt_object *); struct bt_ref { - long count; + unsigned long count; bt_object_release_func release; }; @@ -51,6 +51,8 @@ void bt_ref_get(struct bt_ref *ref) { assert(ref); ref->count++; + /* Overflow check. */ + assert(ref->count); } static inline @@ -58,7 +60,6 @@ void bt_ref_put(struct bt_ref *ref) { assert(ref); /* Only assert if the object has opted-in for reference counting. */ - assert(!ref->release || ref->count > 0); if ((--ref->count) == 0 && ref->release) { ref->release((struct bt_object *) ref); } diff --git a/lib/plugin-system/Makefile.am b/lib/plugin-system/Makefile.am index e3f9614e..30cb0ed0 100644 --- a/lib/plugin-system/Makefile.am +++ b/lib/plugin-system/Makefile.am @@ -13,3 +13,6 @@ libplugin_system_la_SOURCES = \ source.c \ sink.c \ iterator.c + +libplugin_system_la_LIBADD = \ + notification/libplugin-system-notification.la diff --git a/lib/plugin-system/notification/Makefile.am b/lib/plugin-system/notification/Makefile.am index 255659a1..1271c6eb 100644 --- a/lib/plugin-system/notification/Makefile.am +++ b/lib/plugin-system/notification/Makefile.am @@ -4,4 +4,6 @@ noinst_LTLIBRARIES = libplugin-system-notification.la # Plug-in system library libplugin_system_notification_la_SOURCES = \ - notification.c + notification.c \ + packet.c \ + event.c diff --git a/lib/plugin-system/notification/notification.c b/lib/plugin-system/notification/notification.c index a8bb0882..50aca6f7 100644 --- a/lib/plugin-system/notification/notification.c +++ b/lib/plugin-system/notification/notification.c @@ -26,6 +26,17 @@ #include +BT_HIDDEN +void bt_notification_init(struct bt_notification *notification, + enum bt_notification_type type, + bt_object_release_func release) +{ + assert(type > BT_NOTIFICATION_TYPE_ALL && + type < BT_NOTIFICATION_TYPE_NR); + notification->type = type; + bt_object_init(¬ification->base, release); +} + enum bt_notification_type bt_notification_get_type( struct bt_notification *notification) { diff --git a/lib/plugin-system/notification/packet.c b/lib/plugin-system/notification/packet.c new file mode 100644 index 00000000..0b6649a9 --- /dev/null +++ b/lib/plugin-system/notification/packet.c @@ -0,0 +1,106 @@ +/* + * Babeltrace Plug-in Packet-related Notifications + * + * Copyright 2016 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +static +void bt_notification_start_packet_destroy(struct bt_object *obj) +{ + struct bt_notification_packet_start *notification = + (struct bt_notification_packet_start *) obj; + + BT_PUT(notification->packet); + g_free(notification); +} + +static +void bt_notification_end_packet_destroy(struct bt_object *obj) +{ + struct bt_notification_packet_end *notification = + (struct bt_notification_packet_end *) obj; + + BT_PUT(notification->packet); + g_free(notification); +} + +struct bt_notification *bt_notification_packet_start_create( + struct bt_ctf_packet *packet) +{ + struct bt_notification_packet_start *notification; + + if (!packet) { + goto error; + } + + notification = g_new0(struct bt_notification_packet_start, 1); + bt_notification_init(¬ification->parent, + BT_NOTIFICATION_TYPE_PACKET_START, + bt_notification_start_packet_destroy); + notification->packet = bt_get(packet); + return ¬ification->parent; +error: + return NULL; +} + +struct bt_ctf_packet *bt_notification_packet_start_get_packet( + struct bt_notification *notification) +{ + struct bt_notification_packet_start *packet_start; + + packet_start = container_of(notification, + struct bt_notification_packet_start, parent); + return bt_get(packet_start->packet); +} + +struct bt_notification *bt_notification_packet_end_create( + struct bt_ctf_packet *packet) +{ + struct bt_notification_packet_end *notification; + + if (!packet) { + goto error; + } + + notification = g_new0(struct bt_notification_packet_end, 1); + bt_notification_init(¬ification->parent, + BT_NOTIFICATION_TYPE_PACKET_END, + bt_notification_end_packet_destroy); + notification->packet = bt_get(packet); + return ¬ification->parent; +error: + return NULL; +} + +struct bt_ctf_packet *bt_notification_packet_end_get_packet( + struct bt_notification *notification) +{ + struct bt_notification_packet_end *packet_end; + + packet_end = container_of(notification, + struct bt_notification_packet_end, parent); + return bt_get(packet_end->packet); +} diff --git a/plugins/ctf/common/notif-iter/notif-iter.c b/plugins/ctf/common/notif-iter/notif-iter.c index 37b5da02..ee4cd2be 100644 --- a/plugins/ctf/common/notif-iter/notif-iter.c +++ b/plugins/ctf/common/notif-iter/notif-iter.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -75,9 +77,6 @@ struct stack_entry { struct stack { /* Entries (struct stack_entry *) (top is last element) */ GPtrArray *entries; - - /* Link to owner */ - struct bt_ctf_notif_iter *notit; }; /* State */ @@ -200,13 +199,9 @@ struct stack *stack_new(struct bt_ctf_notif_iter *notit) goto error; } - stack->notit = notit; - return stack; - error: g_free(stack); - return NULL; } @@ -223,14 +218,11 @@ int stack_push(struct stack *stack, struct bt_ctf_field *base) { int ret = 0; struct stack_entry *entry; - struct bt_ctf_notif_iter *notit; assert(stack); assert(base); - notit = stack->notit; entry = g_new0(struct stack_entry, 1); if (!entry) { - PERR("Cannot create new stack entry\n"); ret = -1; goto end; } @@ -445,15 +437,15 @@ enum bt_ctf_notif_iter_status read_dscope_continue_state( } consumed_bits = bt_ctf_btr_continue(notit->btr, notit->buf.addr, - notit->buf.sz, &btr_status); + notit->buf.sz, &btr_status); switch (btr_status) { case BT_CTF_BTR_STATUS_OK: - /* Type was read completely */ + /* Type was read completely. */ notit->state = done_state; break; case BT_CTF_BTR_STATUS_EOF: - /* Stay in this continue state */ + /* Stay in this continue state. */ break; default: PERR("Binary type reader failed to continue\n"); @@ -461,9 +453,8 @@ enum bt_ctf_notif_iter_status read_dscope_continue_state( goto end; } - /* Consume bits now since we know we're not in an error state */ + /* Consume bits now since we know we're not in an error state. */ buf_consume_bits(notit, consumed_bits); - end: return status; } @@ -500,7 +491,7 @@ enum bt_ctf_notif_iter_status read_packet_header_begin_state( /* Packet header type is common to the whole trace */ packet_header_type = bt_ctf_trace_get_packet_header_type( - notit->meta.trace); + notit->meta.trace); if (!packet_header_type) { PERR("Failed to retrieve trace's packet header type\n"); status = BT_CTF_NOTIF_ITER_STATUS_ERROR; @@ -508,13 +499,11 @@ enum bt_ctf_notif_iter_status read_packet_header_begin_state( } status = read_dscope_begin_state(notit, packet_header_type, - STATE_AFTER_TRACE_PACKET_HEADER, - STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE, - ¬it->dscopes.trace_packet_header); - + STATE_AFTER_TRACE_PACKET_HEADER, + STATE_DSCOPE_TRACE_PACKET_HEADER_CONTINUE, + ¬it->dscopes.trace_packet_header); end: BT_PUT(packet_header_type); - return status; } @@ -523,19 +512,21 @@ enum bt_ctf_notif_iter_status read_packet_header_continue_state( struct bt_ctf_notif_iter *notit) { return read_dscope_continue_state(notit, - STATE_AFTER_TRACE_PACKET_HEADER); + STATE_AFTER_TRACE_PACKET_HEADER); } static inline bool is_struct_type(struct bt_ctf_field_type *field_type) { - return bt_ctf_field_type_get_type_id(field_type) == BT_CTF_TYPE_ID_STRUCT; + return bt_ctf_field_type_get_type_id(field_type) == + BT_CTF_TYPE_ID_STRUCT; } static inline bool is_variant_type(struct bt_ctf_field_type *field_type) { - return bt_ctf_field_type_get_type_id(field_type) == BT_CTF_TYPE_ID_VARIANT; + return bt_ctf_field_type_get_type_id(field_type) == + BT_CTF_TYPE_ID_VARIANT; } static inline @@ -548,7 +539,7 @@ enum bt_ctf_notif_iter_status set_current_stream_class(struct bt_ctf_notif_iter /* Is there any "stream_id" field in the packet header? */ packet_header_type = bt_ctf_trace_get_packet_header_type( - notit->meta.trace); + notit->meta.trace); if (!packet_header_type) { PERR("Failed to retrieve trace's packet header type\n"); status = BT_CTF_NOTIF_ITER_STATUS_ERROR; @@ -559,8 +550,8 @@ enum bt_ctf_notif_iter_status set_current_stream_class(struct bt_ctf_notif_iter // TODO: optimalize! stream_id_field_type = - bt_ctf_field_type_structure_get_field_type_by_name( - packet_header_type, "stream_id"); + bt_ctf_field_type_structure_get_field_type_by_name( + packet_header_type, "stream_id"); if (stream_id_field_type) { /* Find appropriate stream class using current stream ID */ struct bt_ctf_field *stream_id_field = NULL; @@ -570,16 +561,16 @@ enum bt_ctf_notif_iter_status set_current_stream_class(struct bt_ctf_notif_iter // TODO: optimalize! stream_id_field = bt_ctf_field_structure_get_field( - notit->dscopes.trace_packet_header, "stream_id"); + notit->dscopes.trace_packet_header, "stream_id"); assert(stream_id_field); ret = bt_ctf_field_unsigned_integer_get_value( - stream_id_field, &stream_id); + stream_id_field, &stream_id); assert(!ret); BT_PUT(stream_id_field); } else { /* Only one stream: pick the first stream class */ assert(bt_ctf_trace_get_stream_class_count( - notit->meta.trace) == 1); + notit->meta.trace) == 1); stream_id = 0; } @@ -587,7 +578,7 @@ enum bt_ctf_notif_iter_status set_current_stream_class(struct bt_ctf_notif_iter // TODO: get by ID notit->meta.stream_class = bt_ctf_trace_get_stream_class( - notit->meta.trace, stream_id); + notit->meta.trace, stream_id); if (!notit->meta.stream_class) { PERR("Cannot find stream class with ID %" PRIu64 "\n", stream_id); @@ -625,7 +616,7 @@ enum bt_ctf_notif_iter_status read_packet_context_begin_state( assert(notit->meta.stream_class); packet_context_type = bt_ctf_stream_class_get_packet_context_type( - notit->meta.stream_class); + notit->meta.stream_class); if (!packet_context_type) { PERR("Failed to retrieve stream class's packet context\n"); status = BT_CTF_NOTIF_ITER_STATUS_ERROR; @@ -633,13 +624,12 @@ enum bt_ctf_notif_iter_status read_packet_context_begin_state( } status = read_dscope_begin_state(notit, packet_context_type, - STATE_AFTER_STREAM_PACKET_CONTEXT, - STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE, - ¬it->dscopes.stream_packet_context); + STATE_AFTER_STREAM_PACKET_CONTEXT, + STATE_DSCOPE_STREAM_PACKET_CONTEXT_CONTINUE, + ¬it->dscopes.stream_packet_context); end: BT_PUT(packet_context_type); - return status; } @@ -648,10 +638,10 @@ enum bt_ctf_notif_iter_status read_packet_context_continue_state( struct bt_ctf_notif_iter *notit) { return read_dscope_continue_state(notit, - STATE_AFTER_STREAM_PACKET_CONTEXT); + STATE_AFTER_STREAM_PACKET_CONTEXT); } -static inline +static enum bt_ctf_notif_iter_status set_current_packet_content_sizes( struct bt_ctf_notif_iter *notit) { @@ -662,16 +652,15 @@ enum bt_ctf_notif_iter_status set_current_packet_content_sizes( assert(notit->dscopes.stream_packet_context); - // TODO: optimalize! packet_size_field = bt_ctf_field_structure_get_field( - notit->dscopes.stream_packet_context, "packet_size"); + notit->dscopes.stream_packet_context, "packet_size"); content_size_field = bt_ctf_field_structure_get_field( - notit->dscopes.stream_packet_context, "content_size"); + notit->dscopes.stream_packet_context, "content_size"); if (packet_size_field) { int ret = bt_ctf_field_unsigned_integer_get_value( - packet_size_field, &packet_size); - assert(!ret); + packet_size_field, &packet_size); + assert(!ret); if (packet_size == 0) { PERR("Decoded packet size is 0\n"); status = BT_CTF_NOTIF_ITER_STATUS_ERROR; @@ -682,9 +671,11 @@ enum bt_ctf_notif_iter_status set_current_packet_content_sizes( goto end; } } + if (content_size_field) { int ret = bt_ctf_field_unsigned_integer_get_value( content_size_field, &content_size); + assert(!ret); } else { content_size = packet_size; @@ -692,11 +683,9 @@ enum bt_ctf_notif_iter_status set_current_packet_content_sizes( notit->cur_packet_size = packet_size; notit->cur_content_size = content_size; - end: BT_PUT(packet_size_field); BT_PUT(content_size_field); - return status; } @@ -730,9 +719,9 @@ enum bt_ctf_notif_iter_status read_event_header_begin_state( } else if (packet_at(notit) > notit->cur_content_size) { /* That's not supposed to happen */ PERR("Cursor passed packet's content size:\n"); - PERR(" Decoded content size: %zu\n", + PERR("\tDecoded content size: %zu\n", notit->cur_content_size); - PERR(" Cursor position: %zu\n", packet_at(notit)); + PERR("\tCursor position: %zu\n", packet_at(notit)); status = BT_CTF_NOTIF_ITER_STATUS_ERROR; goto end; } @@ -751,7 +740,6 @@ enum bt_ctf_notif_iter_status read_event_header_begin_state( STATE_AFTER_STREAM_EVENT_HEADER, STATE_DSCOPE_STREAM_EVENT_HEADER_CONTINUE, ¬it->dscopes.stream_event_header); - end: BT_PUT(event_header_type); @@ -1593,18 +1581,19 @@ end: return selected_field_type; } -static struct bt_ctf_event *create_event(struct bt_ctf_notif_iter *notit) +static +struct bt_ctf_event *create_event(struct bt_ctf_notif_iter *notit) { - struct bt_ctf_event *event; int ret; + struct bt_ctf_event *event; - /* Create event object */ + /* Create event object. */ event = bt_ctf_event_create(notit->meta.event_class); if (!event) { goto error; } - /* Set header, stream event context, context, and payload fields */ + /* Set header, stream event context, context, and payload fields. */ ret = bt_ctf_event_set_header(event, notit->dscopes.stream_event_header); if (ret) { @@ -1629,7 +1618,7 @@ static struct bt_ctf_event *create_event(struct bt_ctf_notif_iter *notit) goto error; } - /* Associate with current packet */ + /* Associate with current packet. */ assert(notit->packet); ret = bt_ctf_event_set_packet(event, notit->packet); if (ret) { @@ -1637,15 +1626,14 @@ static struct bt_ctf_event *create_event(struct bt_ctf_notif_iter *notit) } goto end; - error: BT_PUT(event); - end: return event; } -static void create_packet(struct bt_ctf_notif_iter *notit) +static +void create_packet(struct bt_ctf_notif_iter *notit) { int ret; struct bt_ctf_stream *stream = NULL; @@ -1653,7 +1641,7 @@ static void create_packet(struct bt_ctf_notif_iter *notit) /* Ask the user for the stream */ stream = notit->medium.medops.get_stream(notit->meta.stream_class, - notit->medium.data); + notit->medium.data); if (!stream) { goto error; } @@ -1667,7 +1655,7 @@ static void create_packet(struct bt_ctf_notif_iter *notit) /* Set packet's context and header fields */ if (notit->dscopes.trace_packet_header) { ret = bt_ctf_packet_set_header(packet, - notit->dscopes.trace_packet_header); + notit->dscopes.trace_packet_header); if (ret) { goto error; } @@ -1675,135 +1663,76 @@ static void create_packet(struct bt_ctf_notif_iter *notit) if (notit->dscopes.stream_packet_context) { ret = bt_ctf_packet_set_context(packet, - notit->dscopes.stream_packet_context); + notit->dscopes.stream_packet_context); if (ret) { goto error; } } goto end; - error: BT_PUT(packet); - end: BT_MOVE(notit->packet, packet); } -static void notify_new_packet(struct bt_ctf_notif_iter *notit, - struct bt_ctf_notif_iter_notif **notification) +static +void notify_new_packet(struct bt_ctf_notif_iter *notit, + struct bt_notification **notification) { - struct bt_ctf_notif_iter_notif_new_packet *rnotif; - - rnotif = g_new0(struct bt_ctf_notif_iter_notif_new_packet, 1); - if (!rnotif) { - goto error; - } - - rnotif->base.type = BT_CTF_NOTIF_ITER_NOTIF_NEW_PACKET; + struct bt_notification *ret; - /* Create packet */ + /* Initialize the iterator's current packet */ create_packet(notit); if (!notit->packet) { - goto error; + return; } - rnotif->packet = bt_get(notit->packet); - *notification = (struct bt_ctf_notif_iter_notif *) rnotif; - return; - -error: - bt_ctf_notif_iter_notif_destroy(rnotif); + ret = bt_notification_packet_start_create(notit->packet); + if (!ret) { + return; + } + *notification = ret; } -static void notify_end_of_packet(struct bt_ctf_notif_iter *notit, - struct bt_ctf_notif_iter_notif **notification) +static +void notify_end_of_packet(struct bt_ctf_notif_iter *notit, + struct bt_notification **notification) { - struct bt_ctf_notif_iter_notif_end_of_packet *rnotif; + struct bt_notification *ret; - rnotif = g_new0(struct bt_ctf_notif_iter_notif_end_of_packet, 1); - if (!rnotif) { - goto error; - } - - rnotif->base.type = BT_CTF_NOTIF_ITER_NOTIF_END_OF_PACKET; - - /* Create packet */ - create_packet(notit); if (!notit->packet) { - goto error; + return; } - rnotif->packet = bt_get(notit->packet); - *notification = (struct bt_ctf_notif_iter_notif *) rnotif; - return; - -error: - bt_ctf_notif_iter_notif_destroy(rnotif); + ret = bt_notification_packet_end_create(notit->packet); + if (!ret) { + return; + } + BT_PUT(notit->packet); + *notification = ret; } -static void notify_event(struct bt_ctf_notif_iter *notit, - struct bt_ctf_notif_iter_notif **notification) +static +void notify_event(struct bt_ctf_notif_iter *notit, + struct bt_notification **notification) { - struct bt_ctf_notif_iter_notif_event *rnotif; - struct bt_ctf_event *event = NULL; - - rnotif = g_new0(struct bt_ctf_notif_iter_notif_event, 1); - if (!rnotif) { - goto error; - } - - rnotif->base.type = BT_CTF_NOTIF_ITER_NOTIF_EVENT; + struct bt_ctf_event *event; + struct bt_notification *ret = NULL; /* Create event */ event = create_event(notit); if (!event) { - goto error; - } - - BT_MOVE(rnotif->event, event); - *notification = (struct bt_ctf_notif_iter_notif *) rnotif; - return; - -error: - BT_PUT(event); - bt_ctf_notif_iter_notif_destroy(rnotif); -} - -void bt_ctf_notif_iter_notif_destroy(void *vnotif) -{ - struct bt_ctf_notif_iter_notif *notif = vnotif; - - switch (notif->type) { - case BT_CTF_NOTIF_ITER_NOTIF_NEW_PACKET: - { - struct bt_ctf_notif_iter_notif_new_packet *rnotif = - (struct bt_ctf_notif_iter_notif_new_packet *) notif; - - BT_PUT(rnotif->packet); - break; - } - case BT_CTF_NOTIF_ITER_NOTIF_END_OF_PACKET: - { - struct bt_ctf_notif_iter_notif_end_of_packet *rnotif = - (struct bt_ctf_notif_iter_notif_end_of_packet *) notif; - - BT_PUT(rnotif->packet); - break; + goto end; } - case BT_CTF_NOTIF_ITER_NOTIF_EVENT: - { - struct bt_ctf_notif_iter_notif_event *rnotif = - (struct bt_ctf_notif_iter_notif_event *) notif; - BT_PUT(rnotif->event); - break; - } - default: - assert(false); + ret = bt_notification_event_create(event); + if (!ret) { + goto end; } - - g_free(notif); + *notification = ret; +end: + BT_PUT(event); } struct bt_ctf_notif_iter *bt_ctf_notif_iter_create(struct bt_ctf_trace *trace, @@ -1886,7 +1815,7 @@ void bt_ctf_notif_iter_destroy(struct bt_ctf_notif_iter *notit) enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_next_notification( struct bt_ctf_notif_iter *notit, - struct bt_ctf_notif_iter_notif **notification) + struct bt_notification **notification) { enum bt_ctf_notif_iter_status status = BT_CTF_NOTIF_ITER_STATUS_OK; @@ -1897,10 +1826,10 @@ enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_next_notification( status = handle_state(notit); if (status != BT_CTF_NOTIF_ITER_STATUS_OK) { if (status == BT_CTF_NOTIF_ITER_STATUS_EOF) { - PDBG("Medium operation reported end of file\n"); + PDBG("Medium operation reported end of stream\n"); } else { PERR("Failed to handle state:\n"); - PERR(" State: %d\n", notit->state); + PERR("\tState: %d\n", notit->state); } goto end; } diff --git a/plugins/ctf/common/notif-iter/notif-iter.h b/plugins/ctf/common/notif-iter/notif-iter.h index ed1dbbcd..4c93785f 100644 --- a/plugins/ctf/common/notif-iter/notif-iter.h +++ b/plugins/ctf/common/notif-iter/notif-iter.h @@ -289,7 +289,7 @@ void bt_ctf_notif_iter_reset(struct bt_ctf_notif_iter *notif_iter); * @returns One of #bt_ctf_notif_iter_status values */ enum bt_ctf_notif_iter_status bt_ctf_notif_iter_get_next_notification( - struct bt_ctf_notif_iter *notif_iter, - struct bt_ctf_notif_iter_notif **notification); + struct bt_ctf_notif_iter *notit, + struct bt_notification **notification); #endif /* CTF_NOTIF_ITER_H */ diff --git a/plugins/ctf/fs/data-stream.c b/plugins/ctf/fs/data-stream.c index b29c40a0..64152ed2 100644 --- a/plugins/ctf/fs/data-stream.c +++ b/plugins/ctf/fs/data-stream.c @@ -31,15 +31,16 @@ #include #include #include +#include +#include "file.h" +#include "metadata.h" +#include "../common/notif-iter/notif-iter.h" +#include #define PRINT_ERR_STREAM ctf_fs->error_fp #define PRINT_PREFIX "ctf-fs-data-stream" #include "print.h" -#include "file.h" -#include "metadata.h" -#include "../common/notif-iter/notif-iter.h" - static void ctf_fs_stream_destroy(struct ctf_fs_stream *stream) { if (stream->file) { @@ -95,22 +96,20 @@ static int mmap_next(struct ctf_fs_stream *stream) /* Map new region */ stream->mmap_addr = mmap((void *) 0, stream->mmap_len, - PROT_READ, MAP_PRIVATE, fileno(stream->file->fp), - stream->mmap_offset); + PROT_READ, MAP_PRIVATE, fileno(stream->file->fp), + stream->mmap_offset); if (stream->mmap_addr == MAP_FAILED) { PERR("Cannot memory-map address (size %zu) of file \"%s\" (%p) at offset %zu: %s\n", - stream->mmap_len, stream->file->path->str, - stream->file->fp, stream->mmap_offset, - strerror(errno)); + stream->mmap_len, stream->file->path->str, + stream->file->fp, stream->mmap_offset, + strerror(errno)); goto error; } goto end; - error: stream_munmap(stream); ret = -1; - end: return ret; } @@ -209,15 +208,12 @@ static struct ctf_fs_stream *ctf_fs_stream_create( goto error; } stream->mmap_len = ctf_fs->page_size; - goto end; - error: - /* Do not touch borrowed file */ + /* Do not touch "borrowed" file. */ stream->file = NULL; ctf_fs_stream_destroy(stream); stream = NULL; - end: return stream; } @@ -225,14 +221,14 @@ end: int ctf_fs_data_stream_open_streams(struct ctf_fs_component *ctf_fs) { int ret = 0; + const char *name; GError *error = NULL; GDir *dir = g_dir_open(ctf_fs->trace_path->str, 0, &error); - const char *name; if (!dir) { PERR("Cannot open directory \"%s\": %s (code %d)\n", - ctf_fs->trace_path->str, error->message, - error->code); + ctf_fs->trace_path->str, error->message, + error->code); goto error; } @@ -240,69 +236,63 @@ int ctf_fs_data_stream_open_streams(struct ctf_fs_component *ctf_fs) struct ctf_fs_file *file = NULL; struct ctf_fs_stream *stream = NULL; - if (strcmp(name, CTF_FS_METADATA_FILENAME) == 0) { - /* Ignore the metadata stream */ + if (!strcmp(name, CTF_FS_METADATA_FILENAME)) { + /* Ignore the metadata stream. */ PDBG("Ignoring metadata file \"%s\"\n", - name); + name); continue; } if (name[0] == '.') { PDBG("Ignoring hidden file \"%s\"\n", - name); + name); continue; } - /* Create the file */ + /* Create the file. */ file = ctf_fs_file_create(ctf_fs); if (!file) { PERR("Cannot create stream file object\n"); goto error; } - /* Create full path string */ - g_string_append(file->path, ctf_fs->trace_path->str); - g_string_append(file->path, "/"); - g_string_append(file->path, name); - + /* Create full path string. */ + g_string_append_printf(file->path, "%s/%s", + ctf_fs->trace_path->str, name); if (!g_file_test(file->path->str, G_FILE_TEST_IS_REGULAR)) { PDBG("Ignoring non-regular file \"%s\"\n", name); ctf_fs_file_destroy(file); continue; } - /* Open the file */ + /* Open the file. */ if (ctf_fs_file_open(ctf_fs, file, "rb")) { ctf_fs_file_destroy(file); goto error; } - /* Create a private stream */ + /* Create a private stream. */ stream = ctf_fs_stream_create(ctf_fs, file); if (!stream) { ctf_fs_file_destroy(file); goto error; } - /* Append file to the array of files */ + /* Append file to the array of files. */ g_ptr_array_add(ctf_fs->data_stream.streams, stream); } goto end; - error: ret = -1; - end: if (dir) { g_dir_close(dir); dir = NULL; } - if (error) { g_error_free(error); } - return ret; } @@ -312,17 +302,15 @@ int ctf_fs_data_stream_init(struct ctf_fs_component *ctf_fs, int ret = 0; data_stream->streams = g_ptr_array_new_with_free_func( - (GDestroyNotify) ctf_fs_stream_destroy); + (GDestroyNotify) ctf_fs_stream_destroy); if (!data_stream->streams) { PERR("Cannot allocate array of streams\n"); goto error; } goto end; - error: ret = -1; - end: return ret; } @@ -332,30 +320,44 @@ void ctf_fs_data_stream_fini(struct ctf_fs_data_stream *data_stream) g_ptr_array_free(data_stream->streams, TRUE); } -int ctf_fs_data_stream_get_next_notification( +enum bt_notification_iterator_status ctf_fs_data_stream_get_next_notification( struct ctf_fs_component *ctf_fs, - struct bt_ctf_notif_iter_notif **notification) + struct bt_notification **notification) { - int ret = 0; - struct ctf_fs_stream *stream = g_ptr_array_index( - ctf_fs->data_stream.streams, 0); enum bt_ctf_notif_iter_status status; + enum bt_notification_iterator_status ret; + /* FIXME, only iterating on one stream for the moment. */ + struct ctf_fs_stream *stream = g_ptr_array_index( + ctf_fs->data_stream.streams, 0); - status = bt_ctf_notif_iter_get_next_notification( - stream->notif_iter, notification); + status = bt_ctf_notif_iter_get_next_notification(stream->notif_iter, + notification); if (status != BT_CTF_NOTIF_ITER_STATUS_OK && status != BT_CTF_NOTIF_ITER_STATUS_EOF) { - goto error; - } - if (status == BT_CTF_NOTIF_ITER_STATUS_EOF) { - *notification = NULL; + goto end; } - goto end; - -error: - ret = -1; - end: + switch (status) { + case BT_CTF_NOTIF_ITER_STATUS_EOF: + /* Not an error, send end of stream notification. */ + /* Subsequent calls to "next" should return BT_NOTIFICATION_STATUS_END */ + /* TODO */ + case BT_CTF_NOTIF_ITER_STATUS_OK: + ret = BT_NOTIFICATION_ITERATOR_STATUS_OK; + break; + case BT_CTF_NOTIF_ITER_STATUS_AGAIN: + /* + * Should not make it this far as this is medium-specific; + * there is nothing for the user to do and it should have been + * handled upstream. + */ + assert(0); + case BT_CTF_NOTIF_ITER_STATUS_INVAL: + /* No argument provided by the user, so don't return INVAL. */ + case BT_CTF_NOTIF_ITER_STATUS_ERROR: + ret = BT_NOTIFICATION_ITERATOR_STATUS_ERROR; + break; + } return ret; } diff --git a/plugins/ctf/fs/data-stream.h b/plugins/ctf/fs/data-stream.h index 60a46e16..23666814 100644 --- a/plugins/ctf/fs/data-stream.h +++ b/plugins/ctf/fs/data-stream.h @@ -41,8 +41,8 @@ BT_HIDDEN int ctf_fs_data_stream_open_streams(struct ctf_fs_component *ctf_fs); BT_HIDDEN -int ctf_fs_data_stream_get_next_notification( +enum bt_notification_iterator_status ctf_fs_data_stream_get_next_notification( struct ctf_fs_component *ctf_fs, - struct bt_ctf_notif_iter_notif **notification); + struct bt_notification **notification); #endif /* CTF_FS_DATA_STREAM_H */ diff --git a/plugins/ctf/fs/fs.c b/plugins/ctf/fs/fs.c index 2e44c317..ba550f2f 100644 --- a/plugins/ctf/fs/fs.c +++ b/plugins/ctf/fs/fs.c @@ -65,8 +65,7 @@ enum bt_notification_iterator_status ctf_fs_iterator_next( struct bt_notification_iterator *iterator) { enum bt_notification_iterator_status ret; - struct bt_ctf_notif_iter_notif *notification; -// struct bt_notification *notification = NULL; + struct bt_notification *notification = NULL; struct ctf_fs_component *ctf_fs; struct bt_component *component = bt_notification_iterator_get_component( iterator); @@ -84,33 +83,8 @@ enum bt_notification_iterator_status ctf_fs_iterator_next( goto end; } - switch (notification->type) { - case BT_CTF_NOTIF_ITER_NOTIF_NEW_PACKET: - { - struct bt_ctf_notif_iter_notif_new_packet *notif = - (struct bt_ctf_notif_iter_notif_new_packet *) notification; - puts(""); - break; - } - case BT_CTF_NOTIF_ITER_NOTIF_EVENT: - { - struct bt_ctf_notif_iter_notif_event *notif = - (struct bt_ctf_notif_iter_notif_event *) notification; - puts("\tevent"); - break; - } - case BT_CTF_NOTIF_ITER_NOTIF_END_OF_PACKET: - { - struct bt_ctf_notif_iter_notif_end_of_packet *notif = - (struct bt_ctf_notif_iter_notif_end_of_packet *) notification; - puts(""); - break; - } - default: - break; - } - - bt_ctf_notif_iter_notif_destroy(notification); + bt_put(ctf_fs->current_notification); + ctf_fs->current_notification = notification; end: return BT_NOTIFICATION_ITERATOR_STATUS_OK; } @@ -163,6 +137,7 @@ enum bt_component_status ctf_fs_iterator_init(struct bt_component *source, if (ret) { goto error; } + end: return ret; error: diff --git a/plugins/ctf/fs/fs.h b/plugins/ctf/fs/fs.h index e568ddd5..31c86827 100644 --- a/plugins/ctf/fs/fs.h +++ b/plugins/ctf/fs/fs.h @@ -37,6 +37,8 @@ static bool ctf_fs_debug; +struct bt_notification_heap; + struct ctf_fs_file { struct ctf_fs_component *ctf_fs; GString *path; @@ -55,6 +57,7 @@ struct ctf_fs_metadata { struct ctf_fs_stream { struct ctf_fs_file *file; struct bt_ctf_stream *stream; + /* FIXME There should be many and ctf_fs_stream should not own them. */ struct bt_ctf_notif_iter *notif_iter; void *mmap_addr; size_t mmap_len; @@ -67,7 +70,7 @@ struct ctf_fs_data_stream { }; struct ctf_fs_iterator { - int dummy; + struct bt_notification_heap *pending_notifications; }; struct ctf_fs_component_options { diff --git a/plugins/text/text.c b/plugins/text/text.c index 9a31041e..40bc1c5e 100644 --- a/plugins/text/text.c +++ b/plugins/text/text.c @@ -116,6 +116,19 @@ static enum bt_component_status handle_notification(struct bt_component *component, struct bt_notification *notification) { + switch (bt_notification_get_type(notification)) { + case BT_NOTIFICATION_TYPE_PACKET_START: + puts(""); + break; + case BT_NOTIFICATION_TYPE_PACKET_END: + puts(""); + break; + case BT_NOTIFICATION_TYPE_EVENT: + puts(""); + break; + default: + puts("Unhandled notification type"); + } return BT_COMPONENT_STATUS_OK; }