From 10bfb3494971a7c429fb00233501a95d883000b5 Mon Sep 17 00:00:00 2001 From: faithwang Date: Mon, 21 Nov 2022 17:30:00 +0800 Subject: [PATCH 1/7] add retry when server crash Signed-off-by: faithwang --- .../core/common/register/hdc_connect.cpp | 65 +------------- frameworks/core/common/register/hdc_jdwp.cpp | 86 ++++++++++++------- frameworks/core/common/register/hdc_jdwp.h | 7 +- 3 files changed, 61 insertions(+), 97 deletions(-) diff --git a/frameworks/core/common/register/hdc_connect.cpp b/frameworks/core/common/register/hdc_connect.cpp index 61164b60e1c..1bc831e9273 100644 --- a/frameworks/core/common/register/hdc_connect.cpp +++ b/frameworks/core/common/register/hdc_connect.cpp @@ -20,7 +20,6 @@ namespace OHOS::Ace { std::unique_ptr g_connectManagement = nullptr; -static uv_loop_t loopMain; static HdcJdwpSimulator *clsHdcJdwpSimulator = nullptr; void ConnectManagement::SetPkgName(const std::string &pkgName) @@ -33,72 +32,12 @@ std::string ConnectManagement::GetPkgName() return pkgName_; } -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); - } -} - -void TryCloseHandle(const uv_handle_t *handle, uv_close_cb closeCallBack) -{ - TryCloseHandle(handle, false, closeCallBack); -} - -void TryCloseHandle(const uv_handle_t *handle) -{ - TryCloseHandle(handle, nullptr); -} - -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) { - LOGE("%{private}s close busy,try:%{private}d", callerName, closeRetry); - } - - if (ptrLoop->active_handles >= maxHandle) { - LOGE("TryCloseLoop issue"); - } - auto clearLoopTask = [](uv_handle_t *handle, void *arg) -> void { - TryCloseHandle(handle); - }; - uv_walk(ptrLoop, clearLoopTask, nullptr); - // If all processing ends, Then return0,this call will block - if (!ptrLoop->active_handles) { - ret = true; - break; - } - if (!uv_run(ptrLoop, UV_RUN_ONCE)) { - ret = true; - break; - } - } else { - ret = true; - break; - } - } - return ret; -} - void FreeInstance() { if (clsHdcJdwpSimulator == nullptr) { return; // if clsHdcJdwpSimulator is nullptr, should return immediately. } - clsHdcJdwpSimulator->FreeContext(); - uv_stop(&loopMain); - TryCloseLoop(&loopMain, "Hdcjdwp exit"); + clsHdcJdwpSimulator->Disconnect(); delete clsHdcJdwpSimulator; clsHdcJdwpSimulator = nullptr; } @@ -118,7 +57,6 @@ void StopConnect() void* HdcConnectRun(void* pkgContent) { - uv_loop_init(&loopMain); if (signal(SIGINT, Stop) == SIG_ERR) { LOGE("jdwp_process signal fail."); } @@ -128,7 +66,6 @@ void* HdcConnectRun(void* pkgContent) LOGE("Connect fail."); return nullptr; } - uv_run(&loopMain, UV_RUN_DEFAULT); return nullptr; } diff --git a/frameworks/core/common/register/hdc_jdwp.cpp b/frameworks/core/common/register/hdc_jdwp.cpp index eefbf85ae0f..ae6a18e4364 100644 --- a/frameworks/core/common/register/hdc_jdwp.cpp +++ b/frameworks/core/common/register/hdc_jdwp.cpp @@ -14,6 +14,9 @@ * */ #include "frameworks/core/common/register/hdc_jdwp.h" + +#include + #include "base/log/log.h" namespace OHOS::Ace { @@ -21,11 +24,13 @@ HdcJdwpSimulator::HdcJdwpSimulator(const std::string pkgName) { pkgName_ = pkgName; ctxPoint_ = (HCtxJdwpSimulator)MallocContext(); + disconnectFlag_ = false; } -void HdcJdwpSimulator::FreeContext() +void HdcJdwpSimulator::Disconnect() { if (ctxPoint_ != nullptr && ctxPoint_->cfd > -1) { + disconnectFlag_ = true; close(ctxPoint_->cfd); ctxPoint_->cfd = -1; } @@ -34,21 +39,28 @@ void HdcJdwpSimulator::FreeContext() HdcJdwpSimulator::~HdcJdwpSimulator() { if (ctxPoint_ != nullptr) { + if (ctxPoint_->cfd > -1) { + disconnectFlag_ = true; + close(ctxPoint_->cfd); + ctxPoint_->cfd = -1; + } delete ctxPoint_; ctxPoint_ = nullptr; } } -void HdcJdwpSimulator::SendToJpid(int fd, const uint8_t *buf, const int bufLen) +bool HdcJdwpSimulator::SendToJpid(int fd, const uint8_t *buf, const int bufLen) { LOGI("SendToJpid: %{public}s, %{public}d", buf, bufLen); ssize_t rc = write(fd, buf, bufLen); if (rc < 0) { LOGE("SendToJpid failed errno:%{public}d", errno); + return false; } + return true; } -void HdcJdwpSimulator::ConnectJpid(void *param) +bool HdcJdwpSimulator::ConnectJpid(void *param) { uint32_t pid_curr = static_cast(getpid()); HdcJdwpSimulator *thisClass = static_cast(param); @@ -56,34 +68,35 @@ void HdcJdwpSimulator::ConnectJpid(void *param) string pkgName = thisClass->pkgName_; uint32_t pkgSize = pkgName.size() + sizeof(JsMsgHeader); uint8_t* info = new (std::nothrow) uint8_t[pkgSize](); - if (!info) { + if (info == nullptr) { LOGE("ConnectJpid new info fail."); - return; + return false; } if (memset_s(info, pkgSize, 0, pkgSize) != EOK) { delete[] info; info = nullptr; - return; + return false; } JsMsgHeader *jsMsg = reinterpret_cast(info); jsMsg->pid = pid_curr; jsMsg->msgLen = pkgSize; LOGI("ConnectJpid send pid:%{public}d, pkgName:%{public}s, msglen:%{public}d", jsMsg->pid, pkgName.c_str(), jsMsg->msgLen); - bool retFail = false; + bool ret = true; if (memcpy_s(info + sizeof(JsMsgHeader), pkgName.size(), &pkgName[0], pkgName.size()) != EOK) { LOGE("ConnectJpid memcpy_s fail :%{public}s.", pkgName.c_str()); - retFail = true; - } - if (!retFail) { + ret = false; + } else { LOGI("ConnectJpid send JS msg:%{public}s", info); - SendToJpid(thisClass->ctxPoint_->cfd, (uint8_t*)info, pkgSize); + ret = SendToJpid(thisClass->ctxPoint_->cfd, (uint8_t*)info, pkgSize); } - if (info) { + if (info != nullptr) { delete[] info; info = nullptr; } + return ret; #endif + return false; } void *HdcJdwpSimulator::MallocContext() @@ -100,7 +113,7 @@ void *HdcJdwpSimulator::MallocContext() bool HdcJdwpSimulator::Connect() { const char jdwp[] = { '\0', 'o', 'h', 'j', 'p', 'i', 'd', '-', 'c', 'o', 'n', 't', 'r', 'o', 'l', 0 }; - if (!ctxPoint_) { + if (ctxPoint_ == nullptr) { LOGE("MallocContext failed"); return false; } @@ -113,25 +126,38 @@ bool HdcJdwpSimulator::Connect() for (size_t i = 0; i < sizeof(jdwp); i++) { caddr.sun_path[i] = jdwp[i]; } - int cfd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (cfd < 0) { - LOGE("socket failed errno:%{public}d", errno); - return false; - } - struct timeval timeout; - timeout.tv_sec = 1; - timeout.tv_usec = 0; - setsockopt(cfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); - size_t caddrLen = sizeof(caddr.sun_family) + sizeof(jdwp) - 1; - int rc = connect(cfd, reinterpret_cast(&caddr), caddrLen); - if (rc != 0) { - LOGE("connect failed errno:%{public}d", errno); - close(cfd); - return false; + while (!disconnectFlag_) { + int cfd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (cfd < 0) { + LOGE("socket failed errno:%{public}d", errno); + return false; + } + ctxPoint_->cfd = cfd; + + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + setsockopt(cfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); + size_t caddrLen = sizeof(caddr.sun_family) + sizeof(jdwp) - 1; + int rc = connect(cfd, reinterpret_cast(&caddr), caddrLen); + if (rc != 0) { + LOGE("connect failed errno:%{public}d", errno); + return false; + } + if (ConnectJpid(this)) { + char recvBuf[100] = { 0 }; // 100 buf size + int ret = recv(cfd, recvBuf, sizeof(recvBuf), 0); // stop when server connect, or retry + if (ret < 0 && (errno != EINTR && errno != EAGAIN)) { + LOGE("jdwp retry connect server errno:%{public}d, ret:%{public}d", errno, ret); + close(ctxPoint_->cfd); + ctxPoint_->cfd = -1; + } else { + return false; + } + } + sleep(2); // connect per 2 second } - ctxPoint_->cfd = cfd; - ConnectJpid(this); return true; } } // namespace OHOS::Ace diff --git a/frameworks/core/common/register/hdc_jdwp.h b/frameworks/core/common/register/hdc_jdwp.h index cf5ac29b6ac..27d1e564a8b 100644 --- a/frameworks/core/common/register/hdc_jdwp.h +++ b/frameworks/core/common/register/hdc_jdwp.h @@ -27,7 +27,7 @@ public: explicit HdcJdwpSimulator(string pkgName); ~HdcJdwpSimulator(); bool Connect(); - void FreeContext(); + void Disconnect(); protected: struct ContextJdwpSimulator { @@ -42,10 +42,11 @@ private: uint32_t pid; }; void *MallocContext(); - static void ConnectJpid(void *param); - static void SendToJpid(int fd, const uint8_t *buf, const int bufLen); + static bool ConnectJpid(void *param); + static bool SendToJpid(int fd, const uint8_t *buf, const int bufLen); HCtxJdwpSimulator ctxPoint_; string pkgName_; + bool disconnectFlag_; }; } // namespace OHOS::Ace #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_REGISTER_HDC_JDWP_H -- Gitee From ca5b0dae8a3a10e452961615ca38dc587f0469f1 Mon Sep 17 00:00:00 2001 From: faithwang Date: Mon, 21 Nov 2022 17:35:33 +0800 Subject: [PATCH 2/7] close fd Signed-off-by: faithwang --- frameworks/core/common/register/hdc_jdwp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frameworks/core/common/register/hdc_jdwp.cpp b/frameworks/core/common/register/hdc_jdwp.cpp index ae6a18e4364..62b25d12990 100644 --- a/frameworks/core/common/register/hdc_jdwp.cpp +++ b/frameworks/core/common/register/hdc_jdwp.cpp @@ -143,6 +143,8 @@ bool HdcJdwpSimulator::Connect() int rc = connect(cfd, reinterpret_cast(&caddr), caddrLen); if (rc != 0) { LOGE("connect failed errno:%{public}d", errno); + close(ctxPoint_->cfd); + ctxPoint_->cfd = -1; return false; } if (ConnectJpid(this)) { -- Gitee From 85548b1f678e73910a3913863134b9020f1f3387 Mon Sep 17 00:00:00 2001 From: faithwang Date: Mon, 21 Nov 2022 19:18:24 +0800 Subject: [PATCH 3/7] retry connect Signed-off-by: faithwang --- frameworks/core/common/register/hdc_jdwp.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frameworks/core/common/register/hdc_jdwp.cpp b/frameworks/core/common/register/hdc_jdwp.cpp index 62b25d12990..425c84e30b7 100644 --- a/frameworks/core/common/register/hdc_jdwp.cpp +++ b/frameworks/core/common/register/hdc_jdwp.cpp @@ -145,13 +145,14 @@ bool HdcJdwpSimulator::Connect() LOGE("connect failed errno:%{public}d", errno); close(ctxPoint_->cfd); ctxPoint_->cfd = -1; - return false; + sleep(2); + continue; } if (ConnectJpid(this)) { char recvBuf[100] = { 0 }; // 100 buf size int ret = recv(cfd, recvBuf, sizeof(recvBuf), 0); // stop when server connect, or retry - if (ret < 0 && (errno != EINTR && errno != EAGAIN)) { - LOGE("jdwp retry connect server errno:%{public}d, ret:%{public}d", errno, ret); + LOGE("jdwp retry connect server errno:%{public}d, ret:%{public}d", errno, ret); + if (errno != EINTR && errno != EAGAIN) { close(ctxPoint_->cfd); ctxPoint_->cfd = -1; } else { -- Gitee From 8f094f413e795d4898daaa72c957b5039659742a Mon Sep 17 00:00:00 2001 From: faithwang Date: Mon, 21 Nov 2022 19:23:12 +0800 Subject: [PATCH 4/7] retry send data Signed-off-by: faithwang --- frameworks/core/common/register/hdc_jdwp.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/frameworks/core/common/register/hdc_jdwp.cpp b/frameworks/core/common/register/hdc_jdwp.cpp index 425c84e30b7..18fe2906dba 100644 --- a/frameworks/core/common/register/hdc_jdwp.cpp +++ b/frameworks/core/common/register/hdc_jdwp.cpp @@ -143,23 +143,17 @@ bool HdcJdwpSimulator::Connect() int rc = connect(cfd, reinterpret_cast(&caddr), caddrLen); if (rc != 0) { LOGE("connect failed errno:%{public}d", errno); - close(ctxPoint_->cfd); - ctxPoint_->cfd = -1; - sleep(2); - continue; - } - if (ConnectJpid(this)) { + } else if (ConnectJpid(this)) { char recvBuf[100] = { 0 }; // 100 buf size int ret = recv(cfd, recvBuf, sizeof(recvBuf), 0); // stop when server connect, or retry LOGE("jdwp retry connect server errno:%{public}d, ret:%{public}d", errno, ret); - if (errno != EINTR && errno != EAGAIN) { - close(ctxPoint_->cfd); - ctxPoint_->cfd = -1; - } else { + if (errno == EINTR || errno == EAGAIN) { return false; } } - sleep(2); // connect per 2 second + close(ctxPoint_->cfd); + ctxPoint_->cfd = -1; + sleep(3); // connect per 3 second } return true; } -- Gitee From ef67cdb4ba6d605f2fe5a3dcff6b8e70f9ea7d54 Mon Sep 17 00:00:00 2001 From: faithwang Date: Wed, 23 Nov 2022 16:04:28 +0800 Subject: [PATCH 5/7] retry recv when EINTR or EAGAIN Signed-off-by: faithwang --- frameworks/core/common/register/hdc_jdwp.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/frameworks/core/common/register/hdc_jdwp.cpp b/frameworks/core/common/register/hdc_jdwp.cpp index 18fe2906dba..53d47b1b365 100644 --- a/frameworks/core/common/register/hdc_jdwp.cpp +++ b/frameworks/core/common/register/hdc_jdwp.cpp @@ -145,11 +145,15 @@ bool HdcJdwpSimulator::Connect() LOGE("connect failed errno:%{public}d", errno); } else if (ConnectJpid(this)) { char recvBuf[100] = { 0 }; // 100 buf size - int ret = recv(cfd, recvBuf, sizeof(recvBuf), 0); // stop when server connect, or retry - LOGE("jdwp retry connect server errno:%{public}d, ret:%{public}d", errno, ret); - if (errno == EINTR || errno == EAGAIN) { - return false; - } + bool reRecv = false; + do { + reRecv = false; + int ret = recv(cfd, recvBuf, sizeof(recvBuf), 0); // stop when server connect, or retry + LOGE("jdwp retry connect server errno:%{public}d, ret:%{public}d", errno, ret); + if (errno == EINTR || errno == EAGAIN) { + reRecv = true; + } + } while (reRecv); } close(ctxPoint_->cfd); ctxPoint_->cfd = -1; -- Gitee From 381be842ede063dc5120dd76c2c4609b73ffe80c Mon Sep 17 00:00:00 2001 From: faithwang Date: Wed, 23 Nov 2022 21:19:40 +0800 Subject: [PATCH 6/7] fix codingstyle Signed-off-by: faithwang --- frameworks/core/common/register/hdc_jdwp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/core/common/register/hdc_jdwp.cpp b/frameworks/core/common/register/hdc_jdwp.cpp index 53d47b1b365..7644f809b14 100644 --- a/frameworks/core/common/register/hdc_jdwp.cpp +++ b/frameworks/core/common/register/hdc_jdwp.cpp @@ -145,15 +145,15 @@ bool HdcJdwpSimulator::Connect() LOGE("connect failed errno:%{public}d", errno); } else if (ConnectJpid(this)) { char recvBuf[100] = { 0 }; // 100 buf size - bool reRecv = false; - do { + bool reRecv = false; + do { reRecv = false; int ret = recv(cfd, recvBuf, sizeof(recvBuf), 0); // stop when server connect, or retry LOGE("jdwp retry connect server errno:%{public}d, ret:%{public}d", errno, ret); if (errno == EINTR || errno == EAGAIN) { reRecv = true; } - } while (reRecv); + } while (reRecv); } close(ctxPoint_->cfd); ctxPoint_->cfd = -1; -- Gitee From 99dd102c96758a511a09702b9b44ba360224ee0f Mon Sep 17 00:00:00 2001 From: faithwang Date: Thu, 24 Nov 2022 15:13:12 +0800 Subject: [PATCH 7/7] fix double close Signed-off-by: faithwang --- frameworks/core/common/register/hdc_jdwp.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frameworks/core/common/register/hdc_jdwp.cpp b/frameworks/core/common/register/hdc_jdwp.cpp index 7644f809b14..7cbb6834a03 100644 --- a/frameworks/core/common/register/hdc_jdwp.cpp +++ b/frameworks/core/common/register/hdc_jdwp.cpp @@ -155,8 +155,10 @@ bool HdcJdwpSimulator::Connect() } } while (reRecv); } - close(ctxPoint_->cfd); - ctxPoint_->cfd = -1; + if (ctxPoint_->cfd > -1) { + close(ctxPoint_->cfd); + ctxPoint_->cfd = -1; + } sleep(3); // connect per 3 second } return true; -- Gitee