!1541 fix:the problem of process exit

Merge pull request !1541 from yue/OpenHarmony-4.1-Release
This commit is contained in:
openharmony_ci 2024-11-22 10:00:03 +00:00 committed by Gitee
commit 1d5a8537b0
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
14 changed files with 156 additions and 25 deletions

View File

@ -60,7 +60,6 @@ ohos_shared_library("ipc_core") {
"$IPC_CORE_ROOT/src/core/source/message_parcel.cpp",
"$IPC_CORE_ROOT/src/core/source/peer_holder.cpp",
"$IPC_CORE_ROOT/src/core/source/stub_refcount_object.cpp",
"$IPC_CORE_ROOT/src/mock/source/binder_connector.cpp",
"$IPC_CORE_ROOT/src/mock/source/binder_debug.cpp",
"$IPC_CORE_ROOT/src/mock/source/binder_invoker.cpp",
"$IPC_CORE_ROOT/src/mock/source/dbinder_databus_invoker.cpp",

View File

@ -50,7 +50,6 @@ ohos_shared_library("ipc_single") {
"$IPC_CORE_ROOT/src/core/source/message_option.cpp",
"$IPC_CORE_ROOT/src/core/source/message_parcel.cpp",
"$IPC_CORE_ROOT/src/core/source/peer_holder.cpp",
"$IPC_CORE_ROOT/src/mock/source/binder_connector.cpp",
"$IPC_CORE_ROOT/src/mock/source/binder_debug.cpp",
"$IPC_CORE_ROOT/src/mock/source/binder_invoker.cpp",
"$IPC_CORE_ROOT/src/mock/source/hitrace_invoker.cpp",

View File

@ -26,8 +26,12 @@ ohos_shared_library("ipc_common") {
include_dirs = [
"$SUBSYSTEM_DIR/utils/include",
"include",
"//third_party/json/single_include/",
]
sources = [
"../mock/source/binder_connector.cpp",
"source/process_skeleton.cpp",
]
sources = [ "source/process_skeleton.cpp" ]
configs = [
"$SUBSYSTEM_DIR/config:ipc_util_config",

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2024 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
@ -202,13 +202,7 @@ private:
class DestroyInstance {
public:
~DestroyInstance()
{
if (instance_ != nullptr) {
delete instance_;
instance_ = nullptr;
}
}
~DestroyInstance();
};
static IPCProcessSkeleton *instance_;

View File

@ -27,6 +27,11 @@ namespace OHOS {
namespace IPC_SINGLE {
#endif
enum class ThreadType {
NORMAL_THREAD = 0xB0B0B0B0,
IPC_THREAD = 0xB1B1B1B1,
};
class IPCThreadSkeleton {
public:
IPCThreadSkeleton();
@ -46,6 +51,8 @@ public:
static IRemoteInvoker *GetProxyInvoker(IRemoteObject *object);
static bool SetThreadType(ThreadType type);
// Joint Current thread into IPC Work Group
void JoinWorkThread(int proto);
// Quit current thread from IPC work group.
@ -57,6 +64,7 @@ private:
std::atomic<bool> exitFlag_ = false;
std::atomic<bool> usingFlag_ = false;
std::unordered_map<int, IRemoteInvoker *> invokers_;
ThreadType threadType_ = ThreadType::NORMAL_THREAD;
};
#ifdef CONFIG_IPC_SINGLE
} // namespace IPC_SINGLE

View File

@ -62,6 +62,11 @@ public:
bool DetachDeadObject(IRemoteObject *object);
bool IsDeadObject(IRemoteObject *object);
bool GetThreadStopFlag();
void IncreaseThreadCount();
void DecreaseThreadCount();
void NotifyChildThreadStop();
private:
DISALLOW_COPY_AND_MOVE(ProcessSkeleton);
ProcessSkeleton() = default;
@ -94,6 +99,12 @@ private:
std::shared_mutex deadObjectMutex_;
std::map<IRemoteObject *, DeadObjectInfo> deadObjectRecord_;
uint64_t deadObjectClearTime_;
static constexpr size_t MAIN_THREAD_MAX_WAIT_TIME = 3;
std::atomic_bool stopThreadFlag_ = false;
std::mutex threadCountMutex_;
std::condition_variable threadCountCon_;
std::atomic_size_t runningChildThreadNum_ = 0;
};
} // namespace OHOS
#endif // OHOS_IPC_PROCESS_SKELETON_H

View File

@ -156,6 +156,7 @@ void IPCProcessSkeleton::ClearDataResource()
IPCProcessSkeleton::~IPCProcessSkeleton()
{
ZLOGI(LOG_LABEL, "enter");
std::lock_guard<std::mutex> lockGuard(procMutex_);
exitFlag_ = true;
delete threadPool_;
@ -1392,6 +1393,22 @@ sptr<IRemoteObject> IPCProcessSkeleton::QueryDBinderCallbackProxy(sptr<IRemoteOb
return nullptr;
}
#endif
IPCProcessSkeleton::DestroyInstance::~DestroyInstance()
{
if (instance_ == nullptr) {
return;
}
// notify other threads to stop running
auto process = ProcessSkeleton::GetInstance();
if (process != nullptr) {
process->NotifyChildThreadStop();
}
delete instance_;
instance_ = nullptr;
}
#ifdef CONFIG_IPC_SINGLE
} // namespace IPC_SINGLE
#endif

View File

@ -92,6 +92,14 @@ IPCThreadSkeleton::~IPCThreadSkeleton()
delete it->second;
it = invokers_.erase(it);
}
if (threadType_ == ThreadType::IPC_THREAD) {
// subtract thread count when thread exiting
auto process = ProcessSkeleton::GetInstance();
if (process != nullptr) {
process->DecreaseThreadCount();
}
}
}
IRemoteInvoker *IPCThreadSkeleton::GetRemoteInvoker(int proto)
@ -175,6 +183,17 @@ void IPCThreadSkeleton::StopWorkThread(int proto)
invoker->StopWorkThread();
}
}
bool IPCThreadSkeleton::SetThreadType(ThreadType type)
{
IPCThreadSkeleton *current = IPCThreadSkeleton::GetCurrent();
if (current == nullptr) {
return false;
}
current->threadType_ = type;
return true;
}
#ifdef CONFIG_IPC_SINGLE
} // namespace IPC_SINGLE
#endif

View File

@ -28,6 +28,7 @@
#include "ipc_process_skeleton.h"
#include "ipc_thread_skeleton.h"
#include "iremote_invoker.h"
#include "process_skeleton.h"
#include "string"
#include "type_traits"
#include "unistd.h"
@ -48,6 +49,18 @@ IPCWorkThread::~IPCWorkThread()
void *IPCWorkThread::ThreadHandler(void *args)
{
(void)IPCThreadSkeleton::SetThreadType(ThreadType::IPC_THREAD);
ProcessSkeleton *process = ProcessSkeleton::GetInstance();
if (process == nullptr) {
ZLOGE(LOG_LABEL, "get ProcessSkeleton object failed");
return nullptr;
}
if (process->GetThreadStopFlag()) {
ZLOGW(LOG_LABEL, "the stop flag is true, thread start exit");
return nullptr;
}
IPCWorkThread *threadObj = (IPCWorkThread *)args;
IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(threadObj->proto_);
threadObj->threadName_ += "_" + std::to_string(syscall(SYS_gettid));
@ -98,6 +111,17 @@ void IPCWorkThread::StopWorkThread()
void IPCWorkThread::Start(int policy, int proto, std::string threadName)
{
ProcessSkeleton *process = ProcessSkeleton::GetInstance();
if (process == nullptr) {
ZLOGE(LOG_LABEL, "get ProcessSkeleton object failed");
return;
}
if (process->GetThreadStopFlag()) {
ZLOGW(LOG_LABEL, "the stop flag is true, can not create other thread");
return;
}
policy_ = policy;
proto_ = proto;
threadName_ = threadName;
@ -107,6 +131,7 @@ void IPCWorkThread::Start(int policy, int proto, std::string threadName)
ZLOGE(LOG_LABEL, "create thread failed, ret:%{public}d", ret);
return;
}
process->IncreaseThreadCount();
ZLOGD(LOG_LABEL, "create thread, policy:%{public}d proto:%{public}d", policy, proto);
if (pthread_detach(threadId) != 0) {
ZLOGE(LOG_LABEL, "detach error");

View File

@ -17,6 +17,7 @@
#include <cinttypes>
#include "binder_connector.h"
#include "log_tags.h"
#include "ipc_debug.h"
#include "string_ex.h"
@ -240,4 +241,49 @@ void ProcessSkeleton::DetachTimeoutDeadObject()
++it;
}
}
bool ProcessSkeleton::GetThreadStopFlag()
{
return stopThreadFlag_.load();
}
void ProcessSkeleton::IncreaseThreadCount()
{
std::unique_lock<std::mutex> lockGuard(threadCountMutex_);
runningChildThreadNum_.fetch_add(1);
}
void ProcessSkeleton::DecreaseThreadCount()
{
std::unique_lock<std::mutex> lockGuard(threadCountMutex_);
if (runningChildThreadNum_.load() > 0) {
runningChildThreadNum_.fetch_sub(1);
if (runningChildThreadNum_.load() == 0) {
threadCountCon_.notify_one();
}
}
}
void ProcessSkeleton::NotifyChildThreadStop()
{
// set child thread exit flag
stopThreadFlag_.store(true);
// after closeing fd, child threads will be not block in the 'WriteBinder' function
BinderConnector *connector = BinderConnector::GetInstance();
if (connector != nullptr) {
connector->CloseDriverFd();
}
ZLOGI(LOG_LABEL, "start waiting for child thread to exit, child thread num:%{public}zu",
runningChildThreadNum_.load());
std::unique_lock<std::mutex> lockGuard(threadCountMutex_);
threadCountCon_.wait_for(lockGuard,
std::chrono::seconds(MAIN_THREAD_MAX_WAIT_TIME),
[&threadNum = this->runningChildThreadNum_] { return threadNum.load() == 0; });
if (runningChildThreadNum_.load() != 0) {
ZLOGI(LOG_LABEL, "wait timeout, %{public}zu child threads not exiting", runningChildThreadNum_.load());
return;
}
ZLOGI(LOG_LABEL, "wait finished, all child thread have exited");
}
} // namespace OHOS

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2024 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
@ -24,10 +24,6 @@
#endif
namespace OHOS {
#ifdef CONFIG_IPC_SINGLE
namespace IPC_SINGLE {
#endif
#ifdef CONFIG_ACTV_BINDER
typedef void (*ActvBinderJoinThreadFunc)(bool initiative);
typedef void (*ActvBinderSetHandlerInfoFunc)(uint32_t id);
@ -89,6 +85,7 @@ public:
bool IsRealPidSupported();
uint64_t GetSelfTokenID();
uint64_t GetSelfFirstCallerTokenID();
void CloseDriverFd();
#ifdef CONFIG_ACTV_BINDER
bool IsActvBinderSupported();
ActvHandlerInfo *GetActvHandlerInfo(uint32_t id);
@ -109,8 +106,5 @@ private:
ActvBinderConnector actvBinder_;
#endif
};
#ifdef CONFIG_IPC_SINGLE
} // namespace IPC_SINGLE
#endif
} // namespace OHOS
#endif // OHOS_IPC_BINDER_CONNECTOR_H

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2024 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
@ -75,10 +75,7 @@ BinderConnector::~BinderConnector()
vmAddr_ = MAP_FAILED;
}
if (driverFD_ >= 0) {
close(driverFD_);
driverFD_ = -1;
}
CloseDriverFd();
};
bool BinderConnector::IsDriverAlive()
@ -485,6 +482,9 @@ int BinderConnector::WriteBinder(unsigned long request, void *value)
int err = -EINTR;
while (err == -EINTR) {
if (driverFD_ < 0) {
return -EBADF;
}
if (ioctl(driverFD_, request, value) >= 0) {
err = ERR_NONE;
} else {
@ -545,6 +545,15 @@ uint64_t BinderConnector::GetSelfFirstCallerTokenID()
return token;
}
void BinderConnector::CloseDriverFd()
{
if (driverFD_ >= 0) {
int tmpFd = driverFD_;
driverFD_ = -1;
close(tmpFd);
}
}
BinderConnector *BinderConnector::GetInstance()
{
if (instance_ == nullptr) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2024 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
@ -389,6 +389,10 @@ void BinderInvoker::StartWorkLoop()
{
int error;
do {
ProcessSkeleton *process = ProcessSkeleton::GetInstance();
if (process == nullptr || process->GetThreadStopFlag()) {
break;
}
error = TransactWithDriver();
if (error < ERR_NONE && error != -ECONNREFUSED && error != -EBADF) {
ZLOGE(LABEL, "returned unexpected error:%{public}d, aborting", error);

View File

@ -115,6 +115,7 @@ ohos_unittest("BinderConnectorTest") {
]
deps = [
"$IPC_CORE_ROOT/src/core:ipc_common",
"$IPC_TEST_ROOT/auxiliary/native:TestAssistance",
"//third_party/googletest:gtest_main",
]
@ -145,6 +146,7 @@ ohos_unittest("BinderInvokerUnitTest") {
]
deps = [
"$IPC_CORE_ROOT/src/core:ipc_common",
"$IPC_TEST_ROOT/auxiliary/native:TestAssistance",
"//third_party/googletest:gtest_main",
]