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