2 * SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
11 #include <babeltrace2/babeltrace.h>
15 #include "common/assert.h"
16 #include "cpp-common/nlohmann/json.hpp"
19 typedef void (*run_in_comp_cls_init_func
)(bt_self_component
*self_comp
, void *user_data
);
21 struct comp_cls_init_method_data
23 run_in_comp_cls_init_func func
;
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
)
31 comp_cls_init_method_data
*data
= static_cast<comp_cls_init_method_data
*>(init_method_data
);
33 /* Call user function which is expected to abort */
34 data
->func(bt_self_component_source_as_self_component(self_comp
), data
->user_data
);
37 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR
;
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
)
45 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR
;
48 static void run_in_comp_cls_init(run_in_comp_cls_init_func func
, void *user_data
)
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
;
54 struct comp_cls_init_method_data init_method_data
= {
56 .user_data
= user_data
,
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
);
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
);
68 graph
= bt_graph_create(0);
72 * Add source component: this calls the initialization method,
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
);
79 * This point is not expected to be reached as func() is
84 static void run_in_comp_cls_init_defer(bt_self_component
*self_comp
, void *user_data
)
86 cond_trigger_run_in_comp_cls_init_func user_func
=
87 reinterpret_cast<cond_trigger_run_in_comp_cls_init_func
>(user_data
);
92 static void run_trigger(const struct cond_trigger
*trigger
)
94 switch (trigger
->func_type
) {
95 case COND_TRIGGER_FUNC_TYPE_BASIC
:
96 trigger
->func
.basic();
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
));
107 static void list_triggers(const struct cond_trigger triggers
[], size_t trigger_count
)
109 nlohmann::json trigger_array
= nlohmann::json::array();
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
];
116 trigger_obj
["cond-id"] = trigger
.cond_id
;
118 /* Name starts with condition ID */
119 std::string name
= trigger
.cond_id
;
121 if (trigger
.suffix
) {
123 name
+= trigger
.suffix
;
126 trigger_obj
["name"] = std::move(name
);
127 trigger_array
.push_back(std::move(trigger_obj
));
130 auto str
= trigger_array
.dump();
132 std::flush(std::cout
);
135 void cond_main(int argc
, const char *argv
[], const struct cond_trigger triggers
[],
136 size_t trigger_count
)
138 BT_ASSERT(argc
>= 2);
140 if (strcmp(argv
[1], "list") == 0) {
141 list_triggers(triggers
, trigger_count
);
142 } else if (strcmp(argv
[1], "run") == 0) {
145 BT_ASSERT(argc
>= 3);
146 index
= atoi(argv
[2]);
147 BT_ASSERT(index
>= 0 && index
< trigger_count
);
148 run_trigger(&triggers
[index
]);