• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <cstring>
17 #include <iostream>
18 #include <vector>
19 #include <pthread.h>
20 #include <thread>
21 #include <uv.h>
22 #include <securec.h>
23 
24 #include "tooling/client/utils/cli_command.h"
25 #include "tooling/client/session/session.h"
26 #include "tooling/client/tcpServer/tcp_server.h"
27 #include "manager/message_manager.h"
28 
29 namespace OHOS::ArkCompiler::Toolchain {
30 uv_loop_t* g_loop;
31 
ReleaseHandle(uv_async_t * releaseHandle)32 void ReleaseHandle([[maybe_unused]] uv_async_t *releaseHandle)
33 {
34     uv_close(reinterpret_cast<uv_handle_t*>(g_inputSignal), [](uv_handle_t* handle) {
35         if (handle != nullptr) {
36             uv_async_t* asyncHandle = reinterpret_cast<uv_async_t*>(handle);
37             if (asyncHandle->data != nullptr) {
38                 free(asyncHandle->data);
39                 asyncHandle->data = nullptr;
40             }
41             delete asyncHandle;
42             asyncHandle = nullptr;
43             g_inputSignal = nullptr;
44         }
45     });
46 
47     uv_close(reinterpret_cast<uv_handle_t*>(g_socketSignal), [](uv_handle_t* handle) {
48         if (handle != nullptr) {
49             delete reinterpret_cast<uv_async_t*>(handle);
50             handle = nullptr;
51             g_socketSignal = nullptr;
52         }
53     });
54 
55     uv_close(reinterpret_cast<uv_handle_t*>(g_releaseHandle), [](uv_handle_t* handle) {
56         if (handle != nullptr) {
57             delete reinterpret_cast<uv_async_t*>(handle);
58             handle = nullptr;
59             g_releaseHandle = nullptr;
60         }
61     });
62 
63     if (g_loop != nullptr) {
64         uv_stop(g_loop);
65     }
66 }
67 
InputMessageInSession(uint32_t sessionId,std::vector<std::string> & cliCmdStr)68 void InputMessageInSession(uint32_t sessionId, std::vector<std::string>& cliCmdStr)
69 {
70     CliCommand cmd(cliCmdStr, sessionId);
71     cmd.ExecCommand();
72     return;
73 }
74 
InputOnMessage(uv_async_t * handle)75 void InputOnMessage(uv_async_t *handle)
76 {
77     char* msg = static_cast<char*>(handle->data);
78     std::string inputStr = std::string(msg);
79     if (msg != nullptr) {
80         free(msg);
81     }
82     std::vector<std::string> cliCmdStr = Utils::SplitString(inputStr, " ");
83     if (cliCmdStr[0] == "forall") {
84         if (strstr(cliCmdStr[1].c_str(), "session") != nullptr) {
85             std::cout << "command " << cliCmdStr[1] << " not support forall" << std::endl;
86         } else {
87             cliCmdStr.erase(cliCmdStr.begin());
88             SessionManager::getInstance().CmdForAllSessions(std::bind(InputMessageInSession, std::placeholders::_1,
89                                                                       cliCmdStr));
90         }
91     } else {
92         uint32_t sessionId = SessionManager::getInstance().GetCurrentSessionId();
93         InputMessageInSession(sessionId, cliCmdStr);
94     }
95 
96     if (TcpServer::getInstance().IsServerActive()) {
97         TcpServer::getInstance().TcpServerWrite("InputOnMessage");
98     } else {
99         std::cout << ">>> ";
100         fflush(stdout);
101     }
102 }
103 
GetInputCommand(void * arg)104 void GetInputCommand([[maybe_unused]] void *arg)
105 {
106     std::cout << ">>> ";
107     std::string inputStr;
108     while (getline(std::cin, inputStr)) {
109         inputStr.erase(0, inputStr.find_first_not_of(" "));
110         if (inputStr.empty()) {
111             std::cout << ">>> ";
112             continue;
113         }
114         if ((!strcmp(inputStr.c_str(), "quit")) || (!strcmp(inputStr.c_str(), "q"))) {
115             LOGE("arkdb: quit");
116             if (uv_is_active(reinterpret_cast<uv_handle_t*>(g_releaseHandle))) {
117                 uv_async_send(g_releaseHandle);
118             }
119             break;
120         }
121         if (uv_is_active(reinterpret_cast<uv_handle_t*>(g_inputSignal))) {
122             uint32_t len = inputStr.length();
123             char* msg = (char*)malloc(len + 1);
124             if (msg == nullptr) {
125                 continue;
126             }
127             if (strncpy_s(msg, len + 1, inputStr.c_str(), len) != 0) {
128                 if (uv_is_active(reinterpret_cast<uv_handle_t*>(g_releaseHandle))) {
129                     uv_async_send(g_releaseHandle);
130                 }
131                 free(msg);
132                 break;
133             }
134             g_inputSignal->data = std::move(msg);
135             uv_async_send(g_inputSignal);
136         }
137     }
138 }
139 
SocketOnMessage(uv_async_t * handle)140 void SocketOnMessage([[maybe_unused]] uv_async_t *handle)
141 {
142     uint32_t sessionId = 0;
143     std::string message;
144     while (MessageManager::getInstance().MessagePop(sessionId, message)) {
145         Session *session = SessionManager::getInstance().GetSessionById(sessionId);
146         if (session == nullptr) {
147             LOGE("arkdb get session by id %{public}u failed", sessionId);
148             continue;
149         }
150 
151         session->ProcSocketMsg(const_cast<char *>(message.c_str()));
152     }
153 
154     if (TcpServer::getInstance().IsServerActive()) {
155         TcpServer::getInstance().TcpServerWrite("SocketOnMessage");
156     }
157 }
158 
Main(const int argc,const char ** argv)159 int Main(const int argc, const char** argv)
160 {
161     if (argc < 2) { // 2: two parameters
162         LOGE("arkdb is missing a parameter");
163         return -1;
164     }
165     if (strstr(argv[0], "arkdb") != nullptr) {
166         std::string sockInfo(argv[1]);
167         if (SessionManager::getInstance().CreateDefaultSession(sockInfo)) {
168             LOGE("arkdb create default session failed");
169             return -1;
170         }
171 
172         g_loop = uv_default_loop();
173 
174         g_inputSignal = new uv_async_t;
175         uv_async_init(g_loop, g_inputSignal, reinterpret_cast<uv_async_cb>(InputOnMessage));
176 
177         g_socketSignal = new uv_async_t;
178         uv_async_init(g_loop, g_socketSignal, reinterpret_cast<uv_async_cb>(SocketOnMessage));
179 
180         g_releaseHandle = new uv_async_t;
181         uv_async_init(g_loop, g_releaseHandle, reinterpret_cast<uv_async_cb>(ReleaseHandle));
182 
183         if (argc > 2 && strcmp(argv[2], "server") == 0) { // 2: two parameters
184             if (TcpServer::getInstance().CreateTcpServer(argv)) {
185                 LOGE("arkdb create TcpServer failed");
186                 return -1;
187             }
188         } else {
189             uv_thread_t inputTid;
190             uv_thread_create(&inputTid, GetInputCommand, nullptr);
191         }
192 
193         uv_run(g_loop, UV_RUN_DEFAULT);
194     }
195     return 0;
196 }
197 } // OHOS::ArkCompiler::Toolchain
198 
main(int argc,const char ** argv)199 int main(int argc, const char **argv)
200 {
201     return OHOS::ArkCompiler::Toolchain::Main(argc, argv);
202 }
203