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