}
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 */
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)
{
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;
-}
/**
* 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 {
/*
* BabelTrace - Plug-in Event Notification internal
*
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SOFTWARE.
*/
-#include <babeltrace/plugin/notification/notification-internal.h>
-#include <babeltrace/ctf-writer/ref-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/stream.h>
#include <babeltrace/ctf-ir/event.h>
-#include <glib.h>
+#include <babeltrace/plugin/notification/notification-internal.h>
#ifdef __cplusplus
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;
};
/*
* BabelTrace - Plug-in Event Notification
*
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
#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.
*
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
/** 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,
+#ifndef BABELTRACE_PLUGIN_NOTIFICATION_PACKET_INTERNAL_H
+#define BABELTRACE_PLUGIN_NOTIFICATION_PACKET_INTERNAL_H
+
+/*
+ * BabelTrace - Packet-related Notifications
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * 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 <babeltrace/ctf-ir/packet.h>
+#include <babeltrace/plugin/notification/notification-internal.h>
+
+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 */
#define BABELTRACE_PLUGIN_NOTIFICATION_PACKET_H
/*
- * BabelTrace - Plug-in Packet Notifications
+ * BabelTrace - Plug-in Packet-related Notifications
*
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SOFTWARE.
*/
+#include <babeltrace/plugin/notification/notification.h>
+
#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
typedef void (*bt_object_release_func)(struct bt_object *);
struct bt_ref {
- long count;
+ unsigned long count;
bt_object_release_func release;
};
{
assert(ref);
ref->count++;
+ /* Overflow check. */
+ assert(ref->count);
}
static inline
{
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);
}
source.c \
sink.c \
iterator.c
+
+libplugin_system_la_LIBADD = \
+ notification/libplugin-system-notification.la
# Plug-in system library
libplugin_system_notification_la_SOURCES = \
- notification.c
+ notification.c \
+ packet.c \
+ event.c
#include <babeltrace/plugin/notification/notification-internal.h>
+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)
{
--- /dev/null
+/*
+ * Babeltrace Plug-in Packet-related Notifications
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * 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 <babeltrace/compiler.h>
+#include <babeltrace/plugin/notification/packet-internal.h>
+
+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);
+}
#include <babeltrace/ctf-ir/stream.h>
#include <babeltrace/ctf-ir/clock.h>
#include <babeltrace/ctf-ir/event-class.h>
+#include <babeltrace/plugin/notification/packet.h>
+#include <babeltrace/plugin/notification/event.h>
#include <babeltrace/ref.h>
#include <glib.h>
struct stack {
/* Entries (struct stack_entry *) (top is last element) */
GPtrArray *entries;
-
- /* Link to owner */
- struct bt_ctf_notif_iter *notit;
};
/* State */
goto error;
}
- stack->notit = notit;
-
return stack;
-
error:
g_free(stack);
-
return NULL;
}
{
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;
}
}
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");
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;
}
/* 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;
}
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;
}
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
/* 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;
// 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;
// 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;
}
// 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);
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;
}
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;
}
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)
{
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;
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;
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;
}
} 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;
}
STATE_AFTER_STREAM_EVENT_HEADER,
STATE_DSCOPE_STREAM_EVENT_HEADER_CONTINUE,
¬it->dscopes.stream_event_header);
-
end:
BT_PUT(event_header_type);
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) {
goto error;
}
- /* Associate with current packet */
+ /* Associate with current packet. */
assert(notit->packet);
ret = bt_ctf_event_set_packet(event, notit->packet);
if (ret) {
}
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;
/* 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;
}
/* 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;
}
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,
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;
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;
}
* @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 */
#include <inttypes.h>
#include <sys/mman.h>
#include <babeltrace/ctf-ir/stream.h>
+#include <babeltrace/plugin/notification/iterator.h>
+#include "file.h"
+#include "metadata.h"
+#include "../common/notif-iter/notif-iter.h"
+#include <assert.h>
#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) {
/* 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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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 */
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);
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("<packet>");
- 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("</packet>");
- 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;
}
if (ret) {
goto error;
}
+
end:
return ret;
error:
static bool ctf_fs_debug;
+struct bt_notification_heap;
+
struct ctf_fs_file {
struct ctf_fs_component *ctf_fs;
GString *path;
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;
};
struct ctf_fs_iterator {
- int dummy;
+ struct bt_notification_heap *pending_notifications;
};
struct ctf_fs_component_options {
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("<packet>");
+ break;
+ case BT_NOTIFICATION_TYPE_PACKET_END:
+ puts("</packet>");
+ break;
+ case BT_NOTIFICATION_TYPE_EVENT:
+ puts("<event>");
+ break;
+ default:
+ puts("Unhandled notification type");
+ }
return BT_COMPONENT_STATUS_OK;
}