metababel 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,400 @@
1
+ #include "uthash.h"
2
+ #include "utlist.h"
3
+ #include <babeltrace2/babeltrace.h>
4
+ #include <metababel/metababel.h>
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+
8
+ /* Loosely inspired by
9
+ * https://babeltrace.org/docs/v2.0/libbabeltrace2/example-simple-flt-cmp-cls.html
10
+ */
11
+
12
+ static const char *get_port_name(uint64_t current) {
13
+ int num_len = snprintf(NULL, 0, "in%ld", current);
14
+ char *result = (char *)malloc(num_len + 1);
15
+ sprintf(result, "in%ld", current);
16
+ return result;
17
+ }
18
+
19
+ /*
20
+ * Handle Upstream Messages
21
+ */
22
+
23
+ static inline bt_message_iterator_class_next_method_status
24
+ filter_message_iterator_next_initializing(
25
+ bt_self_message_iterator *self_message_iterator,
26
+ bt_message_array_const messages, uint64_t capacity, uint64_t *count) {
27
+ /* Retrieve our private data from the message iterator's user data */
28
+ btx_message_iterator_t *message_iterator_private_data =
29
+ bt_self_message_iterator_get_data(self_message_iterator);
30
+
31
+ /* Call Initialize user callback */
32
+ btx_call_callbacks_initialize_usr_data(
33
+ message_iterator_private_data->common_data,
34
+ &message_iterator_private_data->common_data->usr_data);
35
+ /* Call read callbacks */
36
+ btx_call_callbacks_read_params(
37
+ message_iterator_private_data->common_data,
38
+ message_iterator_private_data->common_data->usr_data,
39
+ message_iterator_private_data->common_data->btx_params);
40
+
41
+ // We need to transition in the procesing state
42
+ message_iterator_private_data->state = BTX_FILTER_STATE_PROCESSING;
43
+ if (message_iterator_private_data->queue)
44
+ message_iterator_private_data->processing_state =
45
+ BTX_FILTER_PROCESSING_STATE_SENDING;
46
+
47
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN;
48
+ }
49
+
50
+ static inline bt_message_iterator_class_next_method_status
51
+ filter_message_iterator_next_processing_sending(
52
+ bt_self_message_iterator *self_message_iterator,
53
+ bt_message_array_const messages, uint64_t capacity, uint64_t *count) {
54
+ /* Retrieve our private data from the message iterator's user data */
55
+ btx_message_iterator_t *message_iterator_private_data =
56
+ bt_self_message_iterator_get_data(self_message_iterator);
57
+
58
+ btx_downstream_move_messages(message_iterator_private_data, messages,
59
+ capacity, count);
60
+
61
+ if (!message_iterator_private_data->queue) {
62
+ message_iterator_private_data->processing_state =
63
+ BTX_FILTER_PROCESSING_STATE_READING;
64
+ }
65
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
66
+ }
67
+
68
+ static inline bt_message_iterator_class_next_method_status
69
+ filter_message_iterator_next_processing_reading(
70
+ bt_self_message_iterator *self_message_iterator,
71
+ bt_message_array_const messages, uint64_t capacity, uint64_t *count) {
72
+ /* Retrieve our private data from the message iterator's user data */
73
+ btx_message_iterator_t *message_iterator_private_data =
74
+ bt_self_message_iterator_get_data(self_message_iterator);
75
+
76
+ common_data_t *common_data = message_iterator_private_data->common_data;
77
+
78
+ /* Consume a batch of messages from the upstream message iterator */
79
+ uint64_t upstream_message_count;
80
+ bt_message_array_const upstream_messages;
81
+
82
+ bt_message_iterator_next_status next_status = bt_message_iterator_next(
83
+ message_iterator_private_data->head_mi->message_iterator,
84
+ &upstream_messages, &upstream_message_count);
85
+
86
+ /* We cannot have any message left in the downstream queue
87
+ * Hence it's safe to pass any error messages downstream.
88
+ */
89
+ switch (next_status) {
90
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_END:
91
+ /* We are setting the state, so this function will never being call twice */
92
+ bt_message_iterator_put_ref(
93
+ message_iterator_private_data->head_mi->message_iterator);
94
+
95
+ CDL_DELETE(message_iterator_private_data->head_mi,
96
+ message_iterator_private_data->head_mi);
97
+ if (!message_iterator_private_data->head_mi) {
98
+ /* Call Finalize user callback */
99
+ btx_call_callbacks_finalize_usr_data(
100
+ message_iterator_private_data->common_data,
101
+ message_iterator_private_data->common_data->usr_data);
102
+ message_iterator_private_data->state = BTX_FILTER_STATE_FINALIZING;
103
+ message_iterator_private_data->processing_state =
104
+ BTX_FILTER_PROCESSING_STATE_FINISHED;
105
+ }
106
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN;
107
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN:
108
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN;
109
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR:
110
+ message_iterator_private_data->state = BTX_FILTER_STATE_ERROR;
111
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR;
112
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR:
113
+ message_iterator_private_data->state = BTX_FILTER_STATE_ERROR;
114
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
115
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_OK:
116
+ break;
117
+ default:
118
+ message_iterator_private_data->state = BTX_FILTER_STATE_ERROR;
119
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
120
+ }
121
+
122
+ /* For each consumed message */
123
+ for (uint64_t upstream_i = 0; upstream_i < upstream_message_count;
124
+ upstream_i++) {
125
+ /* Current message */
126
+ const bt_message *upstream_message = upstream_messages[upstream_i];
127
+ /* Move as is if it's not an event message */
128
+ if (bt_message_get_type(upstream_message) != BT_MESSAGE_TYPE_EVENT) {
129
+ bt_message_put_ref(upstream_message);
130
+ continue;
131
+ }
132
+ /* Borrow the event message's event and its class */
133
+ const bt_event *event =
134
+ bt_message_event_borrow_event_const(upstream_message);
135
+ const bt_event_class *event_class = bt_event_borrow_class_const(event);
136
+
137
+ /* Call dispatcher or forward message downstream */
138
+ name_to_dispatcher_t *s = NULL;
139
+ const char *class_name = bt_event_class_get_name(event_class);
140
+ HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
141
+ if (s) {
142
+ (*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, event);
143
+ /* The message have been consumed, we can discard it */
144
+ bt_message_put_ref(upstream_message);
145
+ } else {
146
+ btx_downstream_push_message(message_iterator_private_data,
147
+ upstream_message);
148
+ }
149
+ }
150
+
151
+ /* Round Robin between Upstream MessageIterator */
152
+ message_iterator_private_data->head_mi =
153
+ message_iterator_private_data->head_mi->next;
154
+
155
+ if (message_iterator_private_data->queue) {
156
+ message_iterator_private_data->processing_state =
157
+ BTX_FILTER_PROCESSING_STATE_SENDING;
158
+ /* optimization */
159
+ return filter_message_iterator_next_processing_sending(
160
+ self_message_iterator, messages, capacity, count);
161
+ } else
162
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN;
163
+ }
164
+
165
+ static inline bt_message_iterator_class_next_method_status
166
+ filter_message_iterator_next_processing(
167
+ bt_self_message_iterator *self_message_iterator,
168
+ bt_message_array_const messages, uint64_t capacity, uint64_t *count) {
169
+ /* Retrieve our private data from the message iterator's user data */
170
+ btx_message_iterator_t *message_iterator_private_data =
171
+ bt_self_message_iterator_get_data(self_message_iterator);
172
+
173
+ switch (message_iterator_private_data->processing_state) {
174
+ case BTX_FILTER_PROCESSING_STATE_READING:
175
+ return filter_message_iterator_next_processing_reading(
176
+ self_message_iterator, messages, capacity, count);
177
+ case BTX_FILTER_PROCESSING_STATE_SENDING:
178
+ return filter_message_iterator_next_processing_sending(
179
+ self_message_iterator, messages, capacity, count);
180
+ case BTX_FILTER_PROCESSING_STATE_FINISHED:
181
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
182
+ default:
183
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
184
+ }
185
+ }
186
+
187
+ static inline bt_message_iterator_class_next_method_status
188
+ filter_message_iterator_next_finalizing(
189
+ bt_self_message_iterator *self_message_iterator,
190
+ bt_message_array_const messages, uint64_t capacity, uint64_t *count) {
191
+ /* Retrieve our private data from the message iterator's user data */
192
+ btx_message_iterator_t *message_iterator_private_data =
193
+ bt_self_message_iterator_get_data(self_message_iterator);
194
+
195
+ // assert(message_iterator_private_data->processing_state ==
196
+ // BTX_FILTER_PROCESSING_STATE_FINISHED);
197
+ if (!message_iterator_private_data->queue) {
198
+ message_iterator_private_data->state = BTX_FILTER_STATE_FINISHED;
199
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
200
+ }
201
+
202
+ btx_downstream_move_messages(message_iterator_private_data, messages,
203
+ capacity, count);
204
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
205
+ }
206
+
207
+ static bt_message_iterator_class_next_method_status
208
+ filter_message_iterator_next(bt_self_message_iterator *self_message_iterator,
209
+ bt_message_array_const messages, uint64_t capacity,
210
+ uint64_t *count) {
211
+
212
+ /* Retrieve our private data from the message iterator's user data */
213
+ btx_message_iterator_t *message_iterator_private_data =
214
+ bt_self_message_iterator_get_data(self_message_iterator);
215
+
216
+ switch (message_iterator_private_data->state) {
217
+ case BTX_FILTER_STATE_INITIALIZING:
218
+ return filter_message_iterator_next_initializing(self_message_iterator,
219
+ messages, capacity, count);
220
+ case BTX_FILTER_STATE_PROCESSING:
221
+ return filter_message_iterator_next_processing(self_message_iterator,
222
+ messages, capacity, count);
223
+ case BTX_FILTER_STATE_FINALIZING:
224
+ return filter_message_iterator_next_finalizing(self_message_iterator,
225
+ messages, capacity, count);
226
+ case BTX_FILTER_STATE_FINISHED:
227
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
228
+ default:
229
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
230
+ }
231
+ }
232
+
233
+ /*
234
+ * Initializes the filter component.
235
+ */
236
+ static bt_component_class_initialize_method_status
237
+ filter_initialize(bt_self_component_filter *self_component_filter,
238
+ bt_self_component_filter_configuration *configuration,
239
+ const bt_value *params, void *initialize_method_data) {
240
+
241
+ /* Allocate a private data structure */
242
+ common_data_t *common_data = calloc(1, sizeof(common_data_t));
243
+ common_data->params = params;
244
+ // Read parameters
245
+ btx_populate_params(common_data);
246
+ bt_value_get_ref(common_data->params);
247
+
248
+ /* Register User Callbacks */
249
+ btx_register_usr_callbacks((void *)common_data);
250
+
251
+ /* Set the component's user data to our private data structure */
252
+ bt_self_component_set_data(
253
+ bt_self_component_filter_as_self_component(self_component_filter),
254
+ common_data);
255
+
256
+ /*
257
+ * Add an input port named `in` to the filter component.
258
+ *
259
+ * This is needed so that this filter component can be connected to
260
+ * a filter or a source component. With a connected upstream
261
+ * component, this filter component's message iterator can create a
262
+ * message iterator to consume messages.
263
+ *
264
+ * Add an output port named `out` to the filter component.
265
+ *
266
+ * This is needed so that this filter component can be connected to
267
+ * a filter or a sink component. Once a downstream component is
268
+ * connected, it can create our message iterator.
269
+ */
270
+
271
+ common_data->component =
272
+ bt_self_component_filter_as_component_filter(self_component_filter);
273
+
274
+ const uint64_t current =
275
+ bt_component_filter_get_input_port_count(common_data->component);
276
+
277
+ bt_self_component_filter_add_input_port(self_component_filter,
278
+ get_port_name(current), NULL, NULL);
279
+
280
+ bt_self_component_filter_add_output_port(self_component_filter, "out", NULL,
281
+ NULL);
282
+
283
+ /* Create message that will be used by the filter */
284
+ bt_self_component *self_component =
285
+ bt_self_component_filter_as_self_component(self_component_filter);
286
+ /* Create a `trace_class` and all the children classes (stream and events) */
287
+ bt_trace_class *trace_class =
288
+ btx_downstream_trace_class_create_rec(self_component);
289
+ /* Instantiate a `downstream_trace` of `trace_class` and all the children
290
+ * stream */
291
+ common_data->downstream_trace = btx_downstream_trace_create_rec(trace_class);
292
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
293
+ }
294
+
295
+ bt_component_class_port_connected_method_status
296
+ filter_input_port_connected(bt_self_component_filter *self_comp,
297
+ bt_self_component_port_input *self_port,
298
+ const bt_port_output *other_port) {
299
+ const uint64_t current = bt_component_filter_get_input_port_count(
300
+ bt_self_component_filter_as_component_filter(self_comp));
301
+ bt_self_component_filter_add_input_port(self_comp, get_port_name(current),
302
+ NULL, NULL);
303
+ return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
304
+ }
305
+ /*
306
+ * Initializes the message iterator.
307
+ */
308
+ static bt_message_iterator_class_initialize_method_status
309
+ filter_message_iterator_initialize(
310
+ bt_self_message_iterator *self_message_iterator,
311
+ bt_self_message_iterator_configuration *configuration,
312
+ bt_self_component_port_output *self_port) {
313
+ /* Allocate a private data structure */
314
+ btx_message_iterator_t *message_iterator_private_data =
315
+ calloc(1, sizeof(btx_message_iterator_t));
316
+
317
+ /* Retrieve the component's private data from its user data */
318
+ common_data_t *common_data = bt_self_component_get_data(
319
+ bt_self_message_iterator_borrow_component(self_message_iterator));
320
+
321
+ /* Save a link to the self_message_iterator */
322
+ common_data->self_message_iterator = self_message_iterator;
323
+
324
+ /* Keep a link to the component's private data */
325
+ message_iterator_private_data->common_data = common_data;
326
+
327
+ /* Create the upstream message iterators */
328
+ for (uint64_t i = 0;
329
+ i < bt_component_filter_get_input_port_count(common_data->component);
330
+ i++) {
331
+ bt_self_component_port_input *self_port =
332
+ bt_self_component_filter_borrow_input_port_by_index(
333
+ (bt_self_component_filter *)common_data->component, i);
334
+
335
+ const bt_port *port = bt_self_component_port_as_port(
336
+ bt_self_component_port_input_as_self_component_port(self_port));
337
+
338
+ /* Skip non-connected port */
339
+ if (!bt_port_is_connected(port))
340
+ continue;
341
+
342
+ el_mi *mi = (el_mi *)malloc(sizeof *mi);
343
+ bt_message_iterator_create_from_message_iterator(
344
+ self_message_iterator, self_port, &mi->message_iterator);
345
+ CDL_APPEND(message_iterator_private_data->head_mi, mi);
346
+ }
347
+
348
+ /* Set the message iterator's user data to our private data structure */
349
+ bt_self_message_iterator_set_data(self_message_iterator,
350
+ message_iterator_private_data);
351
+
352
+ message_iterator_private_data->state = BTX_FILTER_STATE_INITIALIZING;
353
+ message_iterator_private_data->processing_state =
354
+ BTX_FILTER_PROCESSING_STATE_READING;
355
+
356
+ return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
357
+ }
358
+
359
+ static void filter_finalize(bt_self_component_filter *self_component_filter) {
360
+ common_data_t *common_data = bt_self_component_get_data(
361
+ bt_self_component_filter_as_self_component(self_component_filter));
362
+ // We allocate it, we need to free it
363
+ free(common_data->btx_params);
364
+ bt_value_put_ref(common_data->params);
365
+ free(common_data);
366
+ }
367
+
368
+ static void filter_message_iterator_finalize(
369
+ bt_self_message_iterator *self_message_iterator) {
370
+ /* Retrieve our private data from the message iterator's user data */
371
+ btx_message_iterator_t *message_iterator_private_data =
372
+ bt_self_message_iterator_get_data(self_message_iterator);
373
+
374
+ struct el *elt, *tmp;
375
+ DL_FOREACH_SAFE(message_iterator_private_data->pool, elt, tmp) {
376
+ DL_DELETE(message_iterator_private_data->pool, elt);
377
+ free(elt);
378
+ }
379
+
380
+ /* Free the allocated structure */
381
+ free(message_iterator_private_data);
382
+ }
383
+
384
+ /* Mandatory */
385
+ BT_PLUGIN_MODULE();
386
+
387
+ BT_PLUGIN(<%= options[:plugin_name] %>);
388
+ BT_PLUGIN_FILTER_COMPONENT_CLASS(<%= options[:component_name] %>,
389
+ filter_message_iterator_next);
390
+
391
+ BT_PLUGIN_FILTER_COMPONENT_CLASS_INITIALIZE_METHOD(<%= options[:component_name] %>,
392
+ filter_initialize);
393
+ BT_PLUGIN_FILTER_COMPONENT_CLASS_FINALIZE_METHOD(<%= options[:component_name] %>,
394
+ filter_finalize);
395
+ BT_PLUGIN_FILTER_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD(
396
+ <%= options[:component_name] %>, filter_message_iterator_initialize);
397
+ BT_PLUGIN_FILTER_COMPONENT_CLASS_MESSAGE_ITERATOR_CLASS_FINALIZE_METHOD(
398
+ <%= options[:component_name] %>, filter_message_iterator_finalize);
399
+ BT_PLUGIN_FILTER_COMPONENT_CLASS_INPUT_PORT_CONNECTED_METHOD(
400
+ <%= options[:component_name] %>, filter_input_port_connected);
@@ -0,0 +1,7 @@
1
+ #include <metababel/btx_component.h>
2
+ <% if ['SOURCE', 'FILTER'].include?(options[:component_type]) %>
3
+ #include <metababel/btx_downstream.h>
4
+ <% end %>
5
+ <% if ['FILTER', 'SINK'].include?(options[:component_type]) %>
6
+ #include <metababel/btx_upstream.h>
7
+ <% end %>
@@ -0,0 +1,166 @@
1
+ #include "uthash.h"
2
+ #include <babeltrace2/babeltrace.h>
3
+ #include <metababel/metababel.h>
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+
7
+ /* Loosely based by
8
+ * https://babeltrace.org/docs/v2.0/libbabeltrace2/example-simple-sink-cmp-cls.html
9
+ */
10
+
11
+ /*
12
+ * Consume Message
13
+ */
14
+
15
+ static bt_component_class_sink_consume_method_status
16
+ sink_consume(bt_self_component_sink *self_component_sink) {
17
+ bt_component_class_sink_consume_method_status status =
18
+ BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
19
+
20
+ /* Retrieve our private data from the component's user data */
21
+ /* This containt user data and the message iterator */
22
+ common_data_t *common_data = bt_self_component_get_data(
23
+ bt_self_component_sink_as_self_component(self_component_sink));
24
+
25
+ /* Consume a batch of messages from the upstream message iterator */
26
+ bt_message_array_const messages;
27
+ uint64_t message_count;
28
+ bt_message_iterator_next_status next_status = bt_message_iterator_next(
29
+ common_data->message_iterator, &messages, &message_count);
30
+
31
+ switch (next_status) {
32
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_END:
33
+ /* End of iteration: put the message iterator's reference */
34
+ bt_message_iterator_put_ref(common_data->message_iterator);
35
+ status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END;
36
+ goto end;
37
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN:
38
+ status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN;
39
+ goto end;
40
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR:
41
+ status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR;
42
+ goto end;
43
+ case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR:
44
+ status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
45
+ goto end;
46
+ default:
47
+ break;
48
+ }
49
+ /* For each consumed message */
50
+ for (uint64_t i = 0; i < message_count; i++) {
51
+ const bt_message *message = messages[i];
52
+ if (bt_message_get_type(message) != BT_MESSAGE_TYPE_EVENT) {
53
+ continue;
54
+ }
55
+
56
+ /* Borrow the event message's event and its class */
57
+ const bt_event *event = bt_message_event_borrow_event_const(message);
58
+ const bt_event_class *event_class = bt_event_borrow_class_const(event);
59
+
60
+ /* Call dispatcher */
61
+ name_to_dispatcher_t *s = NULL;
62
+ const char *class_name = bt_event_class_get_name(event_class);
63
+ HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
64
+ if (s)
65
+ (*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, event);
66
+
67
+ bt_message_put_ref(message);
68
+ }
69
+ end:
70
+ return status;
71
+ }
72
+
73
+ /*
74
+ * Initializes the sink component.
75
+ */
76
+ static bt_component_class_initialize_method_status
77
+ sink_initialize(bt_self_component_sink *self_component_sink,
78
+ bt_self_component_sink_configuration *configuration,
79
+ const bt_value *params, void *initialize_method_data) {
80
+ /* Allocate a private data structure */
81
+ common_data_t *common_data = calloc(1, sizeof(common_data_t));
82
+ common_data->params = params;
83
+ // Read parameters
84
+ btx_populate_params(common_data);
85
+
86
+ bt_value_get_ref(common_data->params);
87
+
88
+ /* Register User Callbacks */
89
+ btx_register_usr_callbacks((void *)common_data);
90
+
91
+ /* Call Initialize user callback */
92
+ btx_call_callbacks_initialize_usr_data(common_data, &common_data->usr_data);
93
+ /* Call read callbacks */
94
+ btx_call_callbacks_read_params(common_data, common_data->usr_data,
95
+ common_data->btx_params);
96
+
97
+ /* Set the component's user data to our private data structure */
98
+ bt_self_component_set_data(
99
+ bt_self_component_sink_as_self_component(self_component_sink),
100
+ common_data);
101
+
102
+ /*
103
+ * Add an input port named `in` to the sink component.
104
+ *
105
+ * This is needed so that this sink component can be connected to a
106
+ * filter or a source component. With a connected upstream
107
+ * component, this sink component can create a message iterator
108
+ * to consume messages.
109
+ */
110
+ bt_self_component_sink_add_input_port(self_component_sink, "in", NULL, NULL);
111
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
112
+ }
113
+
114
+ static void sink_finalize(bt_self_component_sink *self_component_sink) {
115
+ common_data_t *common_data = bt_self_component_get_data(
116
+ bt_self_component_sink_as_self_component(self_component_sink));
117
+
118
+ /* Finalize User Data */
119
+ /* Call Finalize user callback */
120
+ btx_call_callbacks_finalize_usr_data(common_data, common_data->usr_data);
121
+ // We allocate it, we need to free it
122
+ free(common_data->btx_params);
123
+ bt_value_put_ref(common_data->params);
124
+
125
+ /* Free the allocated structure */
126
+ free(common_data);
127
+ }
128
+
129
+ /*
130
+ * Called when the trace processing graph containing the sink component
131
+ * is configured.
132
+ *
133
+ * This is where we can create our upstream message iterator.
134
+ */
135
+ static bt_component_class_sink_graph_is_configured_method_status
136
+ sink_graph_is_configured(bt_self_component_sink *self_component_sink) {
137
+ /* Retrieve our private data from the component's user data */
138
+ common_data_t *common_data = bt_self_component_get_data(
139
+ bt_self_component_sink_as_self_component(self_component_sink));
140
+
141
+ /* Borrow our unique port */
142
+ bt_self_component_port_input *in_port =
143
+ bt_self_component_sink_borrow_input_port_by_index(self_component_sink, 0);
144
+
145
+ /* Create the uptream message iterator */
146
+ bt_message_iterator_create_from_sink_component(
147
+ self_component_sink, in_port, &common_data->message_iterator);
148
+
149
+ return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
150
+ }
151
+
152
+ /* Mandatory */
153
+ BT_PLUGIN_MODULE();
154
+
155
+ BT_PLUGIN(<%= options[:plugin_name] %>);
156
+ // Maybe we should createonly one pluging
157
+ /* Add the output component class */
158
+ BT_PLUGIN_SINK_COMPONENT_CLASS(<%= options[:component_name] %>, sink_consume);
159
+
160
+ BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD(<%= options[:component_name] %>,
161
+ sink_initialize);
162
+ BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(<%= options[:component_name] %>,
163
+ sink_finalize);
164
+
165
+ BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(
166
+ <%= options[:component_name] %>, sink_graph_is_configured);