Commit | Line | Data |
---|---|---|
5d7e8359 PP |
1 | /* |
2 | * SPDX-License-Identifier: GPL-2.0-only | |
3 | * | |
4 | * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com> | |
5 | */ | |
6 | ||
7 | #include <stdlib.h> | |
8 | #include <stdio.h> | |
9 | #include <string.h> | |
10 | #include <assert.h> | |
11 | #include <babeltrace2/babeltrace.h> | |
12 | #include <glib.h> | |
4b4f3ca6 | 13 | #include <iostream> |
5d7e8359 PP |
14 | |
15 | #include "common/assert.h" | |
4b4f3ca6 | 16 | #include "cpp-common/nlohmann/json.hpp" |
053db960 | 17 | #include "utils.hpp" |
5d7e8359 | 18 | |
486428e8 | 19 | typedef void (*run_in_comp_cls_init_func)(bt_self_component *self_comp, void *user_data); |
5d7e8359 | 20 | |
486428e8 SM |
21 | struct comp_cls_init_method_data |
22 | { | |
23 | run_in_comp_cls_init_func func; | |
24 | void *user_data; | |
5d7e8359 PP |
25 | }; |
26 | ||
486428e8 SM |
27 | static bt_component_class_initialize_method_status |
28 | comp_cls_init(bt_self_component_source *self_comp, bt_self_component_source_configuration *conf, | |
29 | const bt_value *params, void *init_method_data) | |
5d7e8359 | 30 | { |
486428e8 | 31 | comp_cls_init_method_data *data = static_cast<comp_cls_init_method_data *>(init_method_data); |
5d7e8359 | 32 | |
486428e8 SM |
33 | /* Call user function which is expected to abort */ |
34 | data->func(bt_self_component_source_as_self_component(self_comp), data->user_data); | |
5d7e8359 | 35 | |
486428e8 SM |
36 | /* Never reached! */ |
37 | return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR; | |
5d7e8359 PP |
38 | } |
39 | ||
486428e8 SM |
40 | static bt_message_iterator_class_next_method_status |
41 | msg_iter_cls_next(bt_self_message_iterator *self_msg_iter, bt_message_array_const msgs, | |
42 | uint64_t capacity, uint64_t *count) | |
5d7e8359 | 43 | { |
486428e8 SM |
44 | /* Not used */ |
45 | return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR; | |
5d7e8359 PP |
46 | } |
47 | ||
486428e8 | 48 | static void run_in_comp_cls_init(run_in_comp_cls_init_func func, void *user_data) |
5d7e8359 | 49 | { |
486428e8 SM |
50 | bt_message_iterator_class *msg_iter_cls; |
51 | bt_component_class_source *comp_cls; | |
52 | bt_component_class_set_method_status set_method_status; | |
53 | bt_graph *graph; | |
54 | struct comp_cls_init_method_data init_method_data = { | |
55 | .func = func, | |
56 | .user_data = user_data, | |
57 | }; | |
58 | ||
59 | /* Create component class */ | |
60 | msg_iter_cls = bt_message_iterator_class_create(msg_iter_cls_next); | |
61 | BT_ASSERT(msg_iter_cls); | |
62 | comp_cls = bt_component_class_source_create("yo", msg_iter_cls); | |
63 | BT_ASSERT(comp_cls); | |
64 | set_method_status = bt_component_class_source_set_initialize_method(comp_cls, comp_cls_init); | |
65 | BT_ASSERT(set_method_status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); | |
66 | ||
67 | /* Create graph */ | |
68 | graph = bt_graph_create(0); | |
69 | BT_ASSERT(graph); | |
70 | ||
71 | /* | |
5d7e8359 PP |
72 | * Add source component: this calls the initialization method, |
73 | * calling `func`. | |
74 | */ | |
486428e8 SM |
75 | (void) bt_graph_add_source_component_with_initialize_method_data( |
76 | graph, comp_cls, "whatever", NULL, &init_method_data, BT_LOGGING_LEVEL_NONE, NULL); | |
5d7e8359 | 77 | |
486428e8 | 78 | /* |
5d7e8359 PP |
79 | * This point is not expected to be reached as func() is |
80 | * expected to abort. | |
81 | */ | |
82 | } | |
83 | ||
486428e8 | 84 | static void run_in_comp_cls_init_defer(bt_self_component *self_comp, void *user_data) |
5d7e8359 | 85 | { |
486428e8 SM |
86 | cond_trigger_run_in_comp_cls_init_func user_func = |
87 | reinterpret_cast<cond_trigger_run_in_comp_cls_init_func>(user_data); | |
5d7e8359 | 88 | |
486428e8 | 89 | user_func(self_comp); |
5d7e8359 PP |
90 | } |
91 | ||
486428e8 | 92 | static void run_trigger(const struct cond_trigger *trigger) |
5d7e8359 | 93 | { |
486428e8 SM |
94 | switch (trigger->func_type) { |
95 | case COND_TRIGGER_FUNC_TYPE_BASIC: | |
96 | trigger->func.basic(); | |
97 | break; | |
98 | case COND_TRIGGER_FUNC_TYPE_RUN_IN_COMP_CLS_INIT: | |
99 | run_in_comp_cls_init(run_in_comp_cls_init_defer, | |
100 | reinterpret_cast<void *>(trigger->func.run_in_comp_cls_init)); | |
101 | break; | |
102 | default: | |
103 | abort(); | |
104 | } | |
5d7e8359 PP |
105 | } |
106 | ||
486428e8 | 107 | static void list_triggers(const struct cond_trigger triggers[], size_t trigger_count) |
5d7e8359 | 108 | { |
4b4f3ca6 | 109 | nlohmann::json trigger_array = nlohmann::json::array(); |
5d7e8359 | 110 | |
4b4f3ca6 SM |
111 | for (size_t i = 0; i < trigger_count; i++) { |
112 | nlohmann::json trigger_obj = nlohmann::json::object(); | |
113 | const cond_trigger& trigger = triggers[i]; | |
5d7e8359 | 114 | |
486428e8 | 115 | /* Condition ID */ |
4b4f3ca6 | 116 | trigger_obj["cond-id"] = trigger.cond_id; |
5d7e8359 | 117 | |
486428e8 | 118 | /* Name starts with condition ID */ |
4b4f3ca6 | 119 | std::string name = trigger.cond_id; |
5d7e8359 | 120 | |
4b4f3ca6 SM |
121 | if (trigger.suffix) { |
122 | name += '-'; | |
123 | name += trigger.suffix; | |
486428e8 | 124 | } |
5d7e8359 | 125 | |
4b4f3ca6 SM |
126 | trigger_obj["name"] = std::move(name); |
127 | trigger_array.push_back(std::move(trigger_obj)); | |
486428e8 | 128 | } |
5d7e8359 | 129 | |
4b4f3ca6 SM |
130 | auto str = trigger_array.dump(); |
131 | std::cout << str; | |
132 | std::flush(std::cout); | |
5d7e8359 PP |
133 | } |
134 | ||
486428e8 SM |
135 | void cond_main(int argc, const char *argv[], const struct cond_trigger triggers[], |
136 | size_t trigger_count) | |
5d7e8359 | 137 | { |
486428e8 SM |
138 | BT_ASSERT(argc >= 2); |
139 | ||
140 | if (strcmp(argv[1], "list") == 0) { | |
141 | list_triggers(triggers, trigger_count); | |
142 | } else if (strcmp(argv[1], "run") == 0) { | |
143 | int index; | |
144 | ||
145 | BT_ASSERT(argc >= 3); | |
146 | index = atoi(argv[2]); | |
147 | BT_ASSERT(index >= 0 && index < trigger_count); | |
148 | run_trigger(&triggers[index]); | |
149 | } | |
5d7e8359 | 150 | } |