mirror of
https://gitee.com/openharmony/communication_ipc
synced 2024-11-26 17:41:17 +00:00
!1541 fix:the problem of process exit
Merge pull request !1541 from yue/OpenHarmony-4.1-Release
This commit is contained in:
commit
1d5a8537b0
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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_;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user