* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "define.h"
#include "HdcJdwpSimulator.h"
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "JDWP_TEST"};
static uv_loop_t loopMain;
static HdcJdwpSimulator *clsHdcJdwpSimulator = nullptr;
static void PrintMessage(const char *fmt, ...)
{
int ret = 0;
va_list ap;
va_start(ap, fmt);
vfprintf(stdout, fmt, ap);
ret = fprintf(stdout, "\n");
va_end(ap);
}
static void TryCloseHandle(const uv_handle_t *handle, bool alwaysCallback,
uv_close_cb closeCallBack)
{
bool hasCallClose = false;
if (handle->loop && !uv_is_closing(handle)) {
uv_close((uv_handle_t *)handle, closeCallBack);
hasCallClose = true;
}
if (!hasCallClose && alwaysCallback) {
closeCallBack((uv_handle_t *)handle);
}
}
static void TryCloseHandle(const uv_handle_t *handle, uv_close_cb closeCallBack)
{
TryCloseHandle(handle, false, closeCallBack);
}
static void TryCloseHandle(const uv_handle_t *handle)
{
TryCloseHandle(handle, nullptr);
}
static bool TryCloseLoop(uv_loop_t *ptrLoop, const char *callerName)
{
uint8_t closeRetry = 0;
bool ret = false;
constexpr int maxRetry = 3;
constexpr int maxHandle = 2;
for (closeRetry = 0; closeRetry < maxRetry; ++closeRetry) {
if (uv_loop_close(ptrLoop) == UV_EBUSY) {
if (closeRetry > maxRetry) {
PrintMessage("%s close busy,try:%d", callerName, closeRetry);
}
if (ptrLoop->active_handles >= maxHandle) {
PrintMessage("TryCloseLoop issue");
}
auto clearLoopTask = [](uv_handle_t *handle, void* ) -> void {
TryCloseHandle(handle);
};
uv_walk(ptrLoop, clearLoopTask, nullptr);
if (!ptrLoop->active_handles) {
ret = true;
break;
}
if (!uv_run(ptrLoop, UV_RUN_ONCE)) {
ret = true;
break;
}
} else {
ret = true;
break;
}
}
return ret;
}
static void FreeInstance()
{
if (clsHdcJdwpSimulator) {
clsHdcJdwpSimulator->stop();
delete clsHdcJdwpSimulator;
clsHdcJdwpSimulator = nullptr;
}
uv_stop(&loopMain);
TryCloseLoop(&loopMain, "Hdcjdwp test exit");
HiLog::Info(LABEL, "jdwp_test_process exit.");
PrintMessage("jdwp_test_process exit.");
}
static void Stop(int )
{
FreeInstance();
_exit(0);
}
int main()
{
uv_loop_init(&loopMain);
HiLog::Info(LABEL, "jdwp_test_process start.");
PrintMessage("jdwp_test_process start.");
if (signal(SIGINT, Stop) == SIG_ERR) {
PrintMessage("jdwp_test_process signal fail.");
}
clsHdcJdwpSimulator = new HdcJdwpSimulator(&loopMain, "com.example.myapplication");
if (!clsHdcJdwpSimulator->Connect()) {
PrintMessage("Connect fail.");
return -1;
}
uv_run(&loopMain, UV_RUN_DEFAULT);
#ifdef JS_JDWP_CONNECT
PrintMessage("Enter 'exit' will stop the test.");
std::string line;
while (std::getline(std::cin, line)) {
if (!strcmp(line.c_str(), "exit")) {
PrintMessage("Exit current process.");
break;
}
}
FreeInstance();
#endif
return 0;
}