X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Fctf%2Ffs-sink%2Fwriter.c;h=fcc618661d29dc658ec5bce59395f071ab712512;hb=50842bdc4c21f3de2b63e29cdac730af8b6dcca6;hp=211a6a9c037c0657bdba27cd993b5bda15866cfe;hpb=d8866baa7f1ae173ac9d9fac0ad55cb28f883cbf;p=babeltrace.git diff --git a/plugins/ctf/fs-sink/writer.c b/plugins/ctf/fs-sink/writer.c index 211a6a9c..fcc61866 100644 --- a/plugins/ctf/fs-sink/writer.c +++ b/plugins/ctf/fs-sink/writer.c @@ -26,18 +26,10 @@ * SOFTWARE. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#define BT_LOG_TAG "PLUGIN-CTF-FS-SINK-WRITER" +#include "logging.h" + +#include #include #include #include @@ -45,13 +37,27 @@ #include "writer.h" #include +static +gboolean empty_trace_map(gpointer key, gpointer value, gpointer user_data) +{ + struct fs_writer *fs_writer = value; + struct writer_component *writer_component = user_data; + + fs_writer->trace_static = 1; + writer_close(writer_component, fs_writer); + + return TRUE; +} + static void destroy_writer_component_data(struct writer_component *writer_component) { bt_put(writer_component->input_iterator); - g_hash_table_destroy(writer_component->stream_map); - g_hash_table_destroy(writer_component->stream_class_map); + + g_hash_table_foreach_remove(writer_component->trace_map, + empty_trace_map, writer_component); g_hash_table_destroy(writer_component->trace_map); + g_string_free(writer_component->base_path, true); g_string_free(writer_component->trace_name_base, true); } @@ -67,21 +73,10 @@ void writer_component_finalize(struct bt_private_component *component) } static -void unref_stream_class(struct bt_ctf_stream_class *writer_stream_class) +void free_fs_writer(struct fs_writer *fs_writer) { - bt_put(writer_stream_class); -} - -static -void unref_stream(struct bt_ctf_stream_class *writer_stream) -{ - bt_put(writer_stream); -} - -static -void unref_trace(struct bt_ctf_writer *writer) -{ - bt_put(writer); + bt_put(fs_writer->writer); + g_free(fs_writer); } static @@ -97,7 +92,6 @@ struct writer_component *create_writer_component(void) writer_component->err = stderr; writer_component->trace_id = 0; writer_component->trace_name_base = g_string_new("trace"); - writer_component->processed_first_event = false; if (!writer_component->trace_name_base) { g_free(writer_component); writer_component = NULL; @@ -108,11 +102,7 @@ struct writer_component *create_writer_component(void) * Reader to writer corresponding structures. */ writer_component->trace_map = g_hash_table_new_full(g_direct_hash, - g_direct_equal, NULL, (GDestroyNotify) unref_trace); - writer_component->stream_class_map = g_hash_table_new_full(g_direct_hash, - g_direct_equal, NULL, (GDestroyNotify) unref_stream_class); - writer_component->stream_map = g_hash_table_new_full(g_direct_hash, - g_direct_equal, NULL, (GDestroyNotify) unref_stream); + g_direct_equal, NULL, (GDestroyNotify) free_fs_writer); end: return writer_component; @@ -133,7 +123,7 @@ enum bt_component_status handle_notification( switch (bt_notification_get_type(notification)) { case BT_NOTIFICATION_TYPE_PACKET_BEGIN: { - struct bt_ctf_packet *packet = + struct bt_packet *packet = bt_notification_packet_begin_get_packet(notification); if (!packet) { @@ -147,7 +137,7 @@ enum bt_component_status handle_notification( } case BT_NOTIFICATION_TYPE_PACKET_END: { - struct bt_ctf_packet *packet = + struct bt_packet *packet = bt_notification_packet_end_get_packet(notification); if (!packet) { @@ -160,14 +150,13 @@ enum bt_component_status handle_notification( } case BT_NOTIFICATION_TYPE_EVENT: { - struct bt_ctf_event *event = bt_notification_event_get_event( + struct bt_event *event = bt_notification_event_get_event( notification); if (!event) { ret = BT_COMPONENT_STATUS_ERROR; goto end; } - ret = BT_COMPONENT_STATUS_OK; ret = writer_output_event(writer_component, event); bt_put(event); if (ret != BT_COMPONENT_STATUS_OK) { @@ -175,8 +164,32 @@ enum bt_component_status handle_notification( } break; } + case BT_NOTIFICATION_TYPE_STREAM_BEGIN: + { + struct bt_stream *stream = + bt_notification_stream_begin_get_stream(notification); + + if (!stream) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + ret = writer_stream_begin(writer_component, stream); + bt_put(stream); + break; + } case BT_NOTIFICATION_TYPE_STREAM_END: + { + struct bt_stream *stream = + bt_notification_stream_end_get_stream(notification); + + if (!stream) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + ret = writer_stream_end(writer_component, stream); + bt_put(stream); break; + } default: puts("Unhandled notification type"); } @@ -192,17 +205,24 @@ void writer_component_port_connected( { struct bt_private_connection *connection; struct writer_component *writer; + enum bt_connection_status conn_status; + static const enum bt_notification_type notif_types[] = { + BT_NOTIFICATION_TYPE_EVENT, + BT_NOTIFICATION_TYPE_PACKET_BEGIN, + BT_NOTIFICATION_TYPE_PACKET_END, + BT_NOTIFICATION_TYPE_STREAM_BEGIN, + BT_NOTIFICATION_TYPE_STREAM_END, + BT_NOTIFICATION_TYPE_SENTINEL, + }; writer = bt_private_component_get_user_data(component); assert(writer); assert(!writer->input_iterator); connection = bt_private_port_get_private_connection(self_port); assert(connection); - writer->input_iterator = - bt_private_connection_create_notification_iterator(connection, - NULL); - - if (!writer->input_iterator) { + conn_status = bt_private_connection_create_notification_iterator( + connection, notif_types, &writer->input_iterator); + if (conn_status != BT_CONNECTION_STATUS_OK) { writer->error = true; } @@ -217,45 +237,70 @@ enum bt_component_status writer_run(struct bt_private_component *component) struct bt_notification_iterator *it; struct writer_component *writer_component = bt_private_component_get_user_data(component); - - it = writer_component->input_iterator; - assert(it); + enum bt_notification_iterator_status it_ret; if (unlikely(writer_component->error)) { ret = BT_COMPONENT_STATUS_ERROR; goto end; } - if (likely(writer_component->processed_first_event)) { - enum bt_notification_iterator_status it_ret; - - it_ret = bt_notification_iterator_next(it); - switch (it_ret) { - case BT_NOTIFICATION_ITERATOR_STATUS_ERROR: - ret = BT_COMPONENT_STATUS_ERROR; - goto end; - case BT_NOTIFICATION_ITERATOR_STATUS_END: - ret = BT_COMPONENT_STATUS_END; - BT_PUT(writer_component->input_iterator); - goto end; - default: - break; - } - } + it = writer_component->input_iterator; + assert(it); + it_ret = bt_notification_iterator_next(it); - notification = bt_notification_iterator_get_notification(it); - if (!notification) { + switch (it_ret) { + case BT_NOTIFICATION_ITERATOR_STATUS_END: + ret = BT_COMPONENT_STATUS_END; + BT_PUT(writer_component->input_iterator); + goto end; + case BT_NOTIFICATION_ITERATOR_STATUS_AGAIN: + ret = BT_COMPONENT_STATUS_AGAIN; + goto end; + case BT_NOTIFICATION_ITERATOR_STATUS_OK: + break; + default: ret = BT_COMPONENT_STATUS_ERROR; goto end; } + notification = bt_notification_iterator_get_notification(it); + assert(notification); ret = handle_notification(writer_component, notification); - writer_component->processed_first_event = true; end: bt_put(notification); return ret; } +static +enum bt_component_status apply_one_bool(const char *key, + struct bt_value *params, + bool *option, + bool *found) +{ + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + struct bt_value *value = NULL; + enum bt_value_status status; + bt_bool bool_val; + + value = bt_value_map_get(params, key); + if (!value) { + goto end; + } + status = bt_value_bool_get(value, &bool_val); + if (status != BT_VALUE_STATUS_OK) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + + *option = (bool) bool_val; + if (found) { + *found = true; + } +end: + bt_put(value); + return ret; +} + BT_HIDDEN enum bt_component_status writer_component_init( struct bt_private_component *component, struct bt_value *params, @@ -266,26 +311,21 @@ enum bt_component_status writer_component_init( struct writer_component *writer_component = create_writer_component(); struct bt_value *value = NULL; const char *path; - void *priv_port; if (!writer_component) { ret = BT_COMPONENT_STATUS_NOMEM; goto end; } - priv_port = bt_private_component_sink_add_input_private_port(component, - "in", NULL); - if (!priv_port) { - ret = BT_COMPONENT_STATUS_NOMEM; + ret = bt_private_component_sink_add_input_private_port(component, + "in", NULL, NULL); + if (ret != BT_COMPONENT_STATUS_OK) { goto end; } - bt_put(priv_port); - value = bt_value_map_get(params, "path"); if (!value || bt_value_is_null(value) || !bt_value_is_string(value)) { - fprintf(writer_component->err, - "[error] output path parameter required\n"); + BT_LOGE_STR("Missing mandatory \"path\" parameter."); ret = BT_COMPONENT_STATUS_INVALID; goto error; } @@ -298,11 +338,18 @@ enum bt_component_status writer_component_init( bt_put(value); writer_component->base_path = g_string_new(path); - if (!writer_component) { + if (!writer_component->base_path) { ret = BT_COMPONENT_STATUS_ERROR; goto error; } + writer_component->single_trace = false; + ret = apply_one_bool("single-trace", params, + &writer_component->single_trace, NULL); + if (ret != BT_COMPONENT_STATUS_OK) { + goto end; + } + ret = bt_private_component_set_user_data(component, writer_component); if (ret != BT_COMPONENT_STATUS_OK) { goto error;