From 34a9ed19bdeb31897a14907dfcf5ff74e10f1e9b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 20 Sep 2016 15:14:45 -0400 Subject: [PATCH] Implement filter component type MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- include/Makefile.am | 1 + include/babeltrace/plugin/filter-internal.h | 3 + include/babeltrace/plugin/filter.h | 2 + include/babeltrace/plugin/input.h | 51 ++++ .../plugin/notification/iterator-internal.h | 1 + include/babeltrace/plugin/sink-internal.h | 10 +- include/babeltrace/plugin/sink.h | 2 + include/babeltrace/plugin/source-internal.h | 2 - include/babeltrace/plugin/source.h | 1 + lib/plugin-system/Makefile.am | 4 +- lib/plugin-system/filter.c | 227 ++++++++++++++++++ lib/plugin-system/input.c | 58 +++++ lib/plugin-system/sink.c | 64 +++-- 13 files changed, 397 insertions(+), 29 deletions(-) create mode 100644 include/babeltrace/plugin/input.h create mode 100644 lib/plugin-system/input.c diff --git a/include/Makefile.am b/include/Makefile.am index 5ae1cc30..ecdb3632 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -119,6 +119,7 @@ noinst_HEADERS = \ babeltrace/plugin/filter-internal.h \ babeltrace/plugin/sink-internal.h \ babeltrace/plugin/source-internal.h \ + babeltrace/plugin/input.h \ babeltrace/plugin/notification/eot-internal.h \ babeltrace/plugin/notification/event-internal.h \ babeltrace/plugin/notification/iterator-internal.h \ diff --git a/include/babeltrace/plugin/filter-internal.h b/include/babeltrace/plugin/filter-internal.h index 271db63f..00498e40 100644 --- a/include/babeltrace/plugin/filter-internal.h +++ b/include/babeltrace/plugin/filter-internal.h @@ -31,6 +31,7 @@ #include #include #include +#include struct bt_value; @@ -41,6 +42,8 @@ struct bt_component_filter_class { struct bt_component_filter { struct bt_component parent; bt_component_filter_init_iterator_cb init_iterator; + bt_component_sink_add_iterator_cb add_iterator; + struct component_input input; }; /** diff --git a/include/babeltrace/plugin/filter.h b/include/babeltrace/plugin/filter.h index a3a8984c..14c6129f 100644 --- a/include/babeltrace/plugin/filter.h +++ b/include/babeltrace/plugin/filter.h @@ -44,6 +44,7 @@ struct bt_notification_iterator; * @param iterator Notification iterator to add * @returns One of #bt_component_status values */ +extern enum bt_component_status bt_component_filter_add_iterator( struct bt_component *component, struct bt_notification_iterator *iterator); @@ -54,6 +55,7 @@ enum bt_component_status bt_component_filter_add_iterator( * @param component Component instance * @returns Notification iterator instance */ +extern struct bt_notification_iterator *bt_component_filter_create_iterator( struct bt_component *component); diff --git a/include/babeltrace/plugin/input.h b/include/babeltrace/plugin/input.h new file mode 100644 index 00000000..e4b861b8 --- /dev/null +++ b/include/babeltrace/plugin/input.h @@ -0,0 +1,51 @@ +#ifndef BABELTRACE_PLUGIN_INPUT_INTERNAL_H +#define BABELTRACE_PLUGIN_INPUT_INTERNAL_H + +/* + * BabelTrace - Component Input + * + * 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 +#include + +struct component_input { + /* Array of struct bt_notification_iterator pointers. */ + GPtrArray *iterators; + unsigned int min_count; + unsigned int max_count; + bool validated; +}; + +BT_HIDDEN +int component_input_init(struct component_input *input); + +BT_HIDDEN +int component_input_validate(struct component_input *input); + +BT_HIDDEN +void component_input_fini(struct component_input *input); + +#endif /* BABELTRACE_PLUGIN_INPUT_INTERNAL_H */ diff --git a/include/babeltrace/plugin/notification/iterator-internal.h b/include/babeltrace/plugin/notification/iterator-internal.h index b56d86c7..c539fd0b 100644 --- a/include/babeltrace/plugin/notification/iterator-internal.h +++ b/include/babeltrace/plugin/notification/iterator-internal.h @@ -30,6 +30,7 @@ #include #include #include +#include struct bt_notification_iterator { struct bt_object base; diff --git a/include/babeltrace/plugin/sink-internal.h b/include/babeltrace/plugin/sink-internal.h index b3a56f95..5d0588aa 100644 --- a/include/babeltrace/plugin/sink-internal.h +++ b/include/babeltrace/plugin/sink-internal.h @@ -31,6 +31,7 @@ #include #include #include +#include struct bt_value; @@ -38,16 +39,13 @@ struct bt_component_sink_class { struct bt_component_class parent; }; -typedef uint32_t notification_mask_t; +//typedef uint32_t notification_mask_t; + struct bt_component_sink { struct bt_component parent; - bt_component_sink_consume_cb consume; bt_component_sink_add_iterator_cb add_iterator; - GPtrArray *inputs; - unsigned int min_input_count; - unsigned int max_input_count; - bool validated_inputs; + struct component_input input; /* notification_mask_t registered_notifications_mask;*/ }; diff --git a/include/babeltrace/plugin/sink.h b/include/babeltrace/plugin/sink.h index 3ea16458..c61d752d 100644 --- a/include/babeltrace/plugin/sink.h +++ b/include/babeltrace/plugin/sink.h @@ -43,6 +43,7 @@ struct bt_notification; * @param iterator Notification iterator to add * @returns One of #bt_component_status values */ +extern enum bt_component_status bt_component_sink_add_iterator( struct bt_component *component, struct bt_notification_iterator *iterator); @@ -53,6 +54,7 @@ enum bt_component_status bt_component_sink_add_iterator( * @param component Component instance * @returns One of #bt_component_status values */ +extern enum bt_component_status bt_component_sink_consume( struct bt_component *component); diff --git a/include/babeltrace/plugin/source-internal.h b/include/babeltrace/plugin/source-internal.h index 70c0196d..90e57dd9 100644 --- a/include/babeltrace/plugin/source-internal.h +++ b/include/babeltrace/plugin/source-internal.h @@ -40,8 +40,6 @@ struct bt_component_source_class { struct bt_component_source { struct bt_component parent; - - /* Component implementation callbacks */ bt_component_source_init_iterator_cb init_iterator; }; diff --git a/include/babeltrace/plugin/source.h b/include/babeltrace/plugin/source.h index 51df185d..8b71ed26 100644 --- a/include/babeltrace/plugin/source.h +++ b/include/babeltrace/plugin/source.h @@ -43,6 +43,7 @@ struct bt_notification_iterator; * @param component Component instance * @returns Notification iterator instance */ +extern struct bt_notification_iterator *bt_component_source_create_iterator( struct bt_component *component); diff --git a/lib/plugin-system/Makefile.am b/lib/plugin-system/Makefile.am index 30cb0ed0..fddea248 100644 --- a/lib/plugin-system/Makefile.am +++ b/lib/plugin-system/Makefile.am @@ -12,7 +12,9 @@ libplugin_system_la_SOURCES = \ plugin.c \ source.c \ sink.c \ - iterator.c + filter.c \ + iterator.c \ + input.c libplugin_system_la_LIBADD = \ notification/libplugin-system-notification.la diff --git a/lib/plugin-system/filter.c b/lib/plugin-system/filter.c index 33cceaef..5ba74051 100644 --- a/lib/plugin-system/filter.c +++ b/lib/plugin-system/filter.c @@ -31,5 +31,232 @@ #include #include #include +#include +enum bt_component_status bt_component_filter_set_iterator_init_cb( + struct bt_component *component, + bt_component_filter_init_iterator_cb init_iterator) +{ + struct bt_component_filter *filter; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + if (component->class->type != BT_COMPONENT_TYPE_FILTER || + !component->initializing) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + filter->init_iterator = init_iterator; +end: + return ret; +} + +enum bt_component_status bt_component_filter_set_add_iterator_cb( + struct bt_component *component, + bt_component_filter_add_iterator_cb add_iterator) +{ + struct bt_component_filter *filter; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + + if (!component) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + if (bt_component_get_type(component) != BT_COMPONENT_TYPE_FILTER) { + ret = BT_COMPONENT_STATUS_UNSUPPORTED; + goto end; + } + + if (!component->initializing) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + filter->add_iterator = add_iterator; +end: + return ret; +} + +enum bt_component_status bt_component_filter_set_minimum_input_count( + struct bt_component *component, + unsigned int minimum) +{ + struct bt_component_filter *filter; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + + if (!component) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + if (bt_component_get_type(component) != BT_COMPONENT_TYPE_FILTER) { + ret = BT_COMPONENT_STATUS_UNSUPPORTED; + goto end; + } + + if (!component->initializing) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + filter->input.min_count = minimum; +end: + return ret; +} + +enum bt_component_status bt_component_filter_set_maximum_input_count( + struct bt_component *component, + unsigned int maximum) +{ + struct bt_component_filter *filter; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + + if (!component) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + if (bt_component_get_type(component) != BT_COMPONENT_TYPE_FILTER) { + ret = BT_COMPONENT_STATUS_UNSUPPORTED; + goto end; + } + + if (!component->initializing) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + filter->input.max_count = maximum; +end: + return ret; +} + +enum bt_component_status +bt_component_filter_get_input_count(struct bt_component *component, + unsigned int *count) +{ + struct bt_component_filter *filter; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + + if (!component || !count) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + if (bt_component_get_type(component) != BT_COMPONENT_TYPE_FILTER) { + ret = BT_COMPONENT_STATUS_UNSUPPORTED; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + *count = (unsigned int) filter->input.iterators->len; +end: + return ret; +} + +enum bt_component_status +bt_component_filter_get_input_iterator(struct bt_component *component, + unsigned int input, struct bt_notification_iterator **iterator) +{ + struct bt_component_filter *filter; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + + if (!component || !iterator) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + if (bt_component_get_type(component) != BT_COMPONENT_TYPE_FILTER) { + ret = BT_COMPONENT_STATUS_UNSUPPORTED; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + if (input >= (unsigned int) filter->input.iterators->len) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + *iterator = bt_get(g_ptr_array_index(filter->input.iterators, input)); +end: + return ret; +} + +enum bt_component_status bt_component_filter_add_iterator( + struct bt_component *component, + struct bt_notification_iterator *iterator) +{ + struct bt_component_filter *filter; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + + if (!component || !iterator) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + if (bt_component_get_type(component) != BT_COMPONENT_TYPE_FILTER) { + ret = BT_COMPONENT_STATUS_UNSUPPORTED; + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + if (filter->input.iterators->len == filter->input.max_count) { + ret = BT_COMPONENT_STATUS_UNSUPPORTED; + goto end; + } + + if (filter->add_iterator) { + ret = filter->add_iterator(component, iterator); + if (ret != BT_COMPONENT_STATUS_OK) { + goto end; + } + } + + g_ptr_array_add(filter->input.iterators, bt_get(iterator)); +end: + return ret; +} + +struct bt_notification_iterator *bt_component_filter_create_iterator( + struct bt_component *component) +{ + enum bt_component_status ret_component; + enum bt_notification_iterator_status ret_iterator; + struct bt_component_filter *filter; + struct bt_notification_iterator *iterator = NULL; + + if (!component) { + goto end; + } + + if (bt_component_get_type(component) != BT_COMPONENT_TYPE_FILTER) { + goto end; + } + + iterator = bt_notification_iterator_create(component); + if (!iterator) { + goto end; + } + + filter = container_of(component, struct bt_component_filter, parent); + assert(filter->init_iterator); + ret_component = filter->init_iterator(component, iterator); + if (ret_component != BT_COMPONENT_STATUS_OK) { + goto error; + } + + ret_iterator = bt_notification_iterator_validate(iterator); + if (ret_iterator != BT_NOTIFICATION_ITERATOR_STATUS_OK) { + goto error; + } +end: + return iterator; +error: + BT_PUT(iterator); + return iterator; +} diff --git a/lib/plugin-system/input.c b/lib/plugin-system/input.c new file mode 100644 index 00000000..26f0d335 --- /dev/null +++ b/lib/plugin-system/input.c @@ -0,0 +1,58 @@ +/* + * input.c + * + * Babeltrace Component Input + * + * 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 + +BT_HIDDEN +int component_input_init(struct component_input *input) +{ + input->min_count = 1; + input->max_count = 1; + input->iterators = g_ptr_array_new_with_free_func(bt_put); + if (!input->iterators) { + return 1; + } + return 0; +} + +BT_HIDDEN +int component_input_validate(struct component_input *input) +{ + if (input->min_count > input->max_count) { + printf_error("Invalid component configuration; minimum input count > maximum input count."); + return 1; + } + return 0; +} + +BT_HIDDEN +void component_input_fini(struct component_input *input) +{ + g_ptr_array_free(input->iterators, TRUE); +} diff --git a/lib/plugin-system/sink.c b/lib/plugin-system/sink.c index d9b33616..0ee51604 100644 --- a/lib/plugin-system/sink.c +++ b/lib/plugin-system/sink.c @@ -46,9 +46,8 @@ enum bt_component_status bt_component_sink_validate( goto end; } - if (sink->min_input_count > sink->max_input_count) { - printf_error("Invalid sink component; minimum input count > maximum input count."); - ret = BT_COMPONENT_STATUS_INVALID; + ret = component_input_validate(&sink->input); + if (ret) { goto end; } end: @@ -61,7 +60,7 @@ void bt_component_sink_destroy(struct bt_component *component) struct bt_component_sink *sink = container_of(component, struct bt_component_sink, parent); - g_ptr_array_free(sink->inputs, TRUE); + component_input_fini(&sink->input); } BT_HIDDEN @@ -82,8 +81,6 @@ struct bt_component *bt_component_sink_create( goto error; } - sink->min_input_count = 1; - sink->max_input_count = 1; /* ret = bt_component_sink_register_notification_type(&sink->parent, BT_NOTIFICATION_TYPE_EVENT); @@ -91,8 +88,7 @@ struct bt_component *bt_component_sink_create( goto error; } */ - sink->inputs = g_ptr_array_new_with_free_func(bt_put); - if (!sink->inputs) { + if (component_input_init(&sink->input)) { goto error; } end: @@ -105,10 +101,10 @@ error: static enum bt_component_status validate_inputs(struct bt_component_sink *sink) { - size_t array_size = sink->inputs->len; + size_t array_size = sink->input.iterators->len; - if (array_size < sink->min_input_count || - array_size > sink->max_input_count) { + if (array_size < sink->input.min_count || + array_size > sink->input.max_count) { return BT_COMPONENT_STATUS_INVALID; } @@ -132,12 +128,12 @@ enum bt_component_status bt_component_sink_consume( } sink = container_of(component, struct bt_component_sink, parent); - if (!sink->validated_inputs) { + if (!sink->input.validated) { ret = validate_inputs(sink); if (ret != BT_COMPONENT_STATUS_OK) { goto end; } - sink->validated_inputs = true; + sink->input.validated = true; } assert(sink->consume); @@ -207,6 +203,34 @@ end: return ret; } +enum bt_component_status bt_component_sink_set_add_iterator_cb( + struct bt_component *component, + bt_component_sink_add_iterator_cb add_iterator) +{ + struct bt_component_sink *sink; + enum bt_component_status ret = BT_COMPONENT_STATUS_OK; + + if (!component) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + if (bt_component_get_type(component) != BT_COMPONENT_TYPE_SINK) { + ret = BT_COMPONENT_STATUS_UNSUPPORTED; + goto end; + } + + if (!component->initializing) { + ret = BT_COMPONENT_STATUS_INVALID; + goto end; + } + + sink = container_of(component, struct bt_component_sink, parent); + sink->add_iterator = add_iterator; +end: + return ret; +} + enum bt_component_status bt_component_sink_set_minimum_input_count( struct bt_component *component, unsigned int minimum) @@ -230,7 +254,7 @@ enum bt_component_status bt_component_sink_set_minimum_input_count( } sink = container_of(component, struct bt_component_sink, parent); - sink->min_input_count = minimum; + sink->input.min_count = minimum; end: return ret; } @@ -258,7 +282,7 @@ enum bt_component_status bt_component_sink_set_maximum_input_count( } sink = container_of(component, struct bt_component_sink, parent); - sink->max_input_count = maximum; + sink->input.max_count = maximum; end: return ret; } @@ -281,7 +305,7 @@ bt_component_sink_get_input_count(struct bt_component *component, } sink = container_of(component, struct bt_component_sink, parent); - *count = (unsigned int) sink->inputs->len; + *count = (unsigned int) sink->input.iterators->len; end: return ret; } @@ -304,12 +328,12 @@ bt_component_sink_get_input_iterator(struct bt_component *component, } sink = container_of(component, struct bt_component_sink, parent); - if (input >= (unsigned int) sink->inputs->len) { + if (input >= (unsigned int) sink->input.iterators->len) { ret = BT_COMPONENT_STATUS_INVALID; goto end; } - *iterator = bt_get(g_ptr_array_index(sink->inputs, input)); + *iterator = bt_get(g_ptr_array_index(sink->input.iterators, input)); end: return ret; } @@ -332,7 +356,7 @@ bt_component_sink_add_iterator(struct bt_component *component, } sink = container_of(component, struct bt_component_sink, parent); - if (sink->inputs->len == sink->max_input_count) { + if (sink->input.iterators->len == sink->input.max_count) { ret = BT_COMPONENT_STATUS_UNSUPPORTED; goto end; } @@ -344,7 +368,7 @@ bt_component_sink_add_iterator(struct bt_component *component, } } - g_ptr_array_add(sink->inputs, bt_get(iterator)); + g_ptr_array_add(sink->input.iterators, bt_get(iterator)); end: return ret; } -- 2.34.1