Commit | Line | Data |
---|---|---|
3c729b9a | 1 | /* |
0235b0db | 2 | * SPDX-License-Identifier: MIT |
3c729b9a | 3 | * |
0235b0db | 4 | * Copyright 2016-2019 EfficiOS Inc. |
3c729b9a PP |
5 | */ |
6 | ||
7 | #define BT_LOG_TAG "CLI/QUERY" | |
8 | #include "logging.h" | |
9 | ||
10 | #include <babeltrace2/babeltrace.h> | |
11 | ||
12 | #include "common/common.h" | |
13 | ||
14 | #include "babeltrace2-query.h" | |
15 | ||
16 | static | |
17 | void set_fail_reason(const char **fail_reason, const char *reason) | |
18 | { | |
19 | if (fail_reason) { | |
20 | *fail_reason = reason; | |
21 | } | |
22 | } | |
23 | ||
3c729b9a PP |
24 | bt_query_executor_query_status cli_query(const bt_component_class *comp_cls, |
25 | const char *obj, const bt_value *params, | |
26 | bt_logging_level log_level, const bt_interrupter *interrupter, | |
27 | const bt_value **user_result, const char **fail_reason) | |
28 | { | |
29 | const bt_value *result = NULL; | |
30 | bt_query_executor_query_status status; | |
31 | bt_query_executor *query_exec; | |
32 | ||
33 | set_fail_reason(fail_reason, "unknown error"); | |
34 | BT_ASSERT(user_result); | |
35 | query_exec = bt_query_executor_create(comp_cls, obj, params); | |
36 | if (!query_exec) { | |
37 | BT_CLI_LOGE_APPEND_CAUSE("Cannot create a query executor."); | |
38 | goto error; | |
39 | } | |
40 | ||
41 | if (bt_query_executor_set_logging_level(query_exec, log_level) != | |
42 | BT_QUERY_EXECUTOR_SET_LOGGING_LEVEL_STATUS_OK) { | |
43 | BT_CLI_LOGE_APPEND_CAUSE( | |
44 | "Cannot set query executor's logging level: " | |
45 | "log-level=%s", | |
46 | bt_common_logging_level_string(log_level)); | |
47 | goto error; | |
48 | } | |
49 | ||
50 | if (interrupter) { | |
51 | if (bt_query_executor_add_interrupter(query_exec, | |
52 | interrupter) != | |
53 | BT_QUERY_EXECUTOR_ADD_INTERRUPTER_STATUS_OK) { | |
54 | BT_CLI_LOGE_APPEND_CAUSE( | |
55 | "Cannot add interrupter to query executor."); | |
56 | goto error; | |
57 | } | |
58 | } | |
59 | ||
60 | while (true) { | |
61 | status = bt_query_executor_query(query_exec, &result); | |
62 | switch (status) { | |
63 | case BT_QUERY_EXECUTOR_QUERY_STATUS_OK: | |
64 | goto ok; | |
65 | case BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN: | |
66 | { | |
67 | const uint64_t sleep_time_us = 100000; | |
68 | ||
69 | if (interrupter && bt_interrupter_is_set(interrupter)) { | |
70 | set_fail_reason(fail_reason, "interrupted by user"); | |
71 | goto error; | |
72 | } | |
73 | ||
74 | /* Wait 100 ms and retry */ | |
75 | BT_LOGD("Got BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN: sleeping: " | |
76 | "time-us=%" PRIu64, sleep_time_us); | |
77 | ||
78 | if (usleep(sleep_time_us)) { | |
79 | if (interrupter && bt_interrupter_is_set(interrupter)) { | |
80 | BT_CLI_LOGW_APPEND_CAUSE( | |
81 | "Query was interrupted by user: " | |
82 | "comp-cls-addr=%p, comp-cls-name=\"%s\", " | |
83 | "query-obj=\"%s\"", comp_cls, | |
84 | bt_component_class_get_name(comp_cls), | |
85 | obj); | |
86 | set_fail_reason(fail_reason, | |
87 | "interrupted by user"); | |
88 | goto error; | |
89 | } | |
90 | } | |
91 | ||
92 | continue; | |
93 | } | |
94 | case BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR: | |
95 | if (interrupter && bt_interrupter_is_set(interrupter)) { | |
96 | set_fail_reason(fail_reason, "interrupted by user"); | |
97 | goto error; | |
98 | } | |
99 | ||
100 | goto error; | |
101 | case BT_QUERY_EXECUTOR_QUERY_STATUS_UNKNOWN_OBJECT: | |
102 | set_fail_reason(fail_reason, "unknown query object"); | |
103 | goto end; | |
104 | case BT_QUERY_EXECUTOR_QUERY_STATUS_MEMORY_ERROR: | |
105 | set_fail_reason(fail_reason, "not enough memory"); | |
106 | goto error; | |
107 | default: | |
108 | BT_LOGF("Unknown query status: status=%s", | |
109 | bt_common_func_status_string(status)); | |
498e7994 | 110 | bt_common_abort(); |
3c729b9a PP |
111 | } |
112 | } | |
113 | ||
114 | ok: | |
115 | *user_result = result; | |
116 | result = NULL; | |
117 | goto end; | |
118 | ||
119 | error: | |
120 | status = BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR; | |
121 | ||
122 | end: | |
123 | bt_query_executor_put_ref(query_exec); | |
124 | bt_value_put_ref(result); | |
125 | return status; | |
126 | } |