Commit | Line | Data |
---|---|---|
3c729b9a PP |
1 | /* |
2 | * Copyright 2016-2019 EfficiOS Inc. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 | * of this software and associated documentation files (the "Software"), to deal | |
6 | * in the Software without restriction, including without limitation the rights | |
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 | * copies of the Software, and to permit persons to whom the Software is | |
9 | * furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice shall be included in | |
12 | * all copies or substantial portions of the Software. | |
13 | * | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
20 | * SOFTWARE. | |
21 | */ | |
22 | ||
23 | #define BT_LOG_TAG "CLI/QUERY" | |
24 | #include "logging.h" | |
25 | ||
26 | #include <babeltrace2/babeltrace.h> | |
27 | ||
28 | #include "common/common.h" | |
29 | ||
30 | #include "babeltrace2-query.h" | |
31 | ||
32 | static | |
33 | void set_fail_reason(const char **fail_reason, const char *reason) | |
34 | { | |
35 | if (fail_reason) { | |
36 | *fail_reason = reason; | |
37 | } | |
38 | } | |
39 | ||
40 | BT_HIDDEN | |
41 | bt_query_executor_query_status cli_query(const bt_component_class *comp_cls, | |
42 | const char *obj, const bt_value *params, | |
43 | bt_logging_level log_level, const bt_interrupter *interrupter, | |
44 | const bt_value **user_result, const char **fail_reason) | |
45 | { | |
46 | const bt_value *result = NULL; | |
47 | bt_query_executor_query_status status; | |
48 | bt_query_executor *query_exec; | |
49 | ||
50 | set_fail_reason(fail_reason, "unknown error"); | |
51 | BT_ASSERT(user_result); | |
52 | query_exec = bt_query_executor_create(comp_cls, obj, params); | |
53 | if (!query_exec) { | |
54 | BT_CLI_LOGE_APPEND_CAUSE("Cannot create a query executor."); | |
55 | goto error; | |
56 | } | |
57 | ||
58 | if (bt_query_executor_set_logging_level(query_exec, log_level) != | |
59 | BT_QUERY_EXECUTOR_SET_LOGGING_LEVEL_STATUS_OK) { | |
60 | BT_CLI_LOGE_APPEND_CAUSE( | |
61 | "Cannot set query executor's logging level: " | |
62 | "log-level=%s", | |
63 | bt_common_logging_level_string(log_level)); | |
64 | goto error; | |
65 | } | |
66 | ||
67 | if (interrupter) { | |
68 | if (bt_query_executor_add_interrupter(query_exec, | |
69 | interrupter) != | |
70 | BT_QUERY_EXECUTOR_ADD_INTERRUPTER_STATUS_OK) { | |
71 | BT_CLI_LOGE_APPEND_CAUSE( | |
72 | "Cannot add interrupter to query executor."); | |
73 | goto error; | |
74 | } | |
75 | } | |
76 | ||
77 | while (true) { | |
78 | status = bt_query_executor_query(query_exec, &result); | |
79 | switch (status) { | |
80 | case BT_QUERY_EXECUTOR_QUERY_STATUS_OK: | |
81 | goto ok; | |
82 | case BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN: | |
83 | { | |
84 | const uint64_t sleep_time_us = 100000; | |
85 | ||
86 | if (interrupter && bt_interrupter_is_set(interrupter)) { | |
87 | set_fail_reason(fail_reason, "interrupted by user"); | |
88 | goto error; | |
89 | } | |
90 | ||
91 | /* Wait 100 ms and retry */ | |
92 | BT_LOGD("Got BT_QUERY_EXECUTOR_QUERY_STATUS_AGAIN: sleeping: " | |
93 | "time-us=%" PRIu64, sleep_time_us); | |
94 | ||
95 | if (usleep(sleep_time_us)) { | |
96 | if (interrupter && bt_interrupter_is_set(interrupter)) { | |
97 | BT_CLI_LOGW_APPEND_CAUSE( | |
98 | "Query was interrupted by user: " | |
99 | "comp-cls-addr=%p, comp-cls-name=\"%s\", " | |
100 | "query-obj=\"%s\"", comp_cls, | |
101 | bt_component_class_get_name(comp_cls), | |
102 | obj); | |
103 | set_fail_reason(fail_reason, | |
104 | "interrupted by user"); | |
105 | goto error; | |
106 | } | |
107 | } | |
108 | ||
109 | continue; | |
110 | } | |
111 | case BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR: | |
112 | if (interrupter && bt_interrupter_is_set(interrupter)) { | |
113 | set_fail_reason(fail_reason, "interrupted by user"); | |
114 | goto error; | |
115 | } | |
116 | ||
117 | goto error; | |
118 | case BT_QUERY_EXECUTOR_QUERY_STATUS_UNKNOWN_OBJECT: | |
119 | set_fail_reason(fail_reason, "unknown query object"); | |
120 | goto end; | |
121 | case BT_QUERY_EXECUTOR_QUERY_STATUS_MEMORY_ERROR: | |
122 | set_fail_reason(fail_reason, "not enough memory"); | |
123 | goto error; | |
124 | default: | |
125 | BT_LOGF("Unknown query status: status=%s", | |
126 | bt_common_func_status_string(status)); | |
498e7994 | 127 | bt_common_abort(); |
3c729b9a PP |
128 | } |
129 | } | |
130 | ||
131 | ok: | |
132 | *user_result = result; | |
133 | result = NULL; | |
134 | goto end; | |
135 | ||
136 | error: | |
137 | status = BT_QUERY_EXECUTOR_QUERY_STATUS_ERROR; | |
138 | ||
139 | end: | |
140 | bt_query_executor_put_ref(query_exec); | |
141 | bt_value_put_ref(result); | |
142 | return status; | |
143 | } |