fix dead lock of create proxy

Signed-off-by: liangshenglin <liangshenglin1@huawei.com>
This commit is contained in:
liangshenglin1 2021-08-20 02:05:20 +00:00 committed by Gitee
parent 589bde9f29
commit 230bd2020c
4 changed files with 33 additions and 65 deletions

View File

@ -70,7 +70,7 @@ public:
std::string GetDataBusName();
int GetProto() const;
void WaitForInit();
void WaitForInit(bool newProxy);
std::u16string GetInterfaceDescriptor();
private:

View File

@ -103,7 +103,6 @@ int IPCObjectProxy::SendRequestInner(bool isLocal, uint32_t code, MessageParcel
std::u16string IPCObjectProxy::GetInterfaceDescriptor()
{
std::lock_guard<std::mutex> lockGuard(initMutex_);
if (!remoteDescriptor_.empty()) {
return remoteDescriptor_;
}
@ -159,34 +158,33 @@ std::string IPCObjectProxy::GetDataBusName()
void IPCObjectProxy::OnFirstStrongRef(const void *objectId)
{
return WaitForInit();
IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
if (invoker != nullptr) {
invoker->AcquireHandle(handle_);
}
}
void IPCObjectProxy::WaitForInit()
void IPCObjectProxy::WaitForInit(bool newProxy)
{
#ifndef CONFIG_IPC_SINGLE
int type = 0;
#endif
{
bool acquire = true;
std::lock_guard<std::mutex> lockGuard(initMutex_);
if (IsObjectDead()) {
ZLOGI(LABEL, "check a dead proxy, init again");
isRemoteDead_ = false;
isFinishInit_ = false;
acquire = false;
}
// check again is this object been initialized
if (isFinishInit_) {
return;
}
IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
if (invoker != nullptr && acquire == true) {
invoker->AcquireHandle(handle_);
}
#ifndef CONFIG_IPC_SINGLE
if (newProxy == true) {
ReleaseProto();
}
type = UpdateProto();
#endif
isFinishInit_ = true;
@ -206,15 +204,15 @@ void IPCObjectProxy::OnLastStrongRef(const void *objectId)
return;
}
if (current->DetachObject(this)) {
if (current->DetachObject(this)) { // if detach successfully, this proxy will be destroyed
#ifndef CONFIG_IPC_SINGLE
ReleaseProto();
#endif
IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
if (invoker != nullptr) {
invoker->ReleaseHandle(handle_);
}
}
#ifndef CONFIG_IPC_SINGLE
ReleaseProto();
#endif
}
@ -412,23 +410,7 @@ void IPCObjectProxy::IncRefToRemote()
void IPCObjectProxy::ReleaseProto()
{
switch (GetProto()) {
case IRemoteObject::IF_PROT_BINDER: {
ZLOGW(LABEL, "it is normal binder, try to delete handle to index");
ReleaseBinderProto();
break;
}
case IRemoteObject::IF_PROT_DATABUS: {
ReleaseDatabusProto();
break;
}
default: {
ZLOGE(LABEL, "ReleaseProto Invalid Type");
break;
}
}
return;
ReleaseDatabusProto();
}
void IPCObjectProxy::SetProto(int proto)
@ -637,24 +619,7 @@ void IPCObjectProxy::ReleaseDatabusProto()
void IPCObjectProxy::ReleaseBinderProto()
{
if (handle_ == 0) {
ZLOGI(LABEL, "%s:handle == 0, do nothing", __func__);
return;
}
if (GetProto() != IRemoteObject::IF_PROT_BINDER) {
ZLOGI(LABEL, "not binder proxy, need do nothing");
return;
}
IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
if (current == nullptr) {
ZLOGE(LABEL, "release proto current is null");
return;
}
(void)current->DetachHandleToIndex(handle_);
return;
// do nothing
}
#endif
} // namespace OHOS

View File

@ -123,6 +123,7 @@ std::u16string IPCProcessSkeleton::MakeHandleDescriptor(int handle)
IRemoteObject *IPCProcessSkeleton::FindOrNewObject(int handle)
{
bool newProxy = false;
IRemoteObject *remoteObject = nullptr;
std::u16string descriptor = MakeHandleDescriptor(handle);
{
@ -142,20 +143,22 @@ IRemoteObject *IPCProcessSkeleton::FindOrNewObject(int handle)
}
}
remoteObject = new IPCObjectProxy(handle, descriptor);
remoteObject->AttemptAcquire(this);
newProxy = true;
auto proxy = new IPCObjectProxy(handle, descriptor);
proxy->AttemptAcquire(this); // AttemptAcquire always returns true as life time is extended
remoteObject = reinterpret_cast<IRemoteObject *>(proxy);
if (!AttachObjectInner(remoteObject)) {
DBINDER_LOGE("attach object fail");
delete remoteObject;
DBINDER_LOGE("attach object failed");
delete proxy;
return nullptr;
}
return remoteObject;
} else {
remoteObject->AttemptAcquire(this);
}
}
IPCObjectProxy *remoteProxy = reinterpret_cast<IPCObjectProxy *>(remoteObject);
remoteProxy->WaitForInit();
remoteProxy->WaitForInit(newProxy);
return remoteObject;
}
@ -233,9 +236,14 @@ bool IPCProcessSkeleton::IsContainsObject(IRemoteObject *object)
bool IPCProcessSkeleton::DetachObject(IRemoteObject *object)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
int strongRef = object->GetSptrRefCount();
if (strongRef > 0) {
DBINDER_LOGI("proxy is still strong referenced:%{public}d", strongRef);
return false;
}
// If it fails, clear it in the destructor.
(void)isContainStub_.erase(object);
std::u16string descriptor = object->GetObjectDescriptor();
if (descriptor.empty()) {
return false;
@ -277,13 +285,8 @@ IRemoteObject *IPCProcessSkeleton::QueryObjectInner(const std::u16string &descri
{
auto it = objects_.find(descriptor);
if (it != objects_.end()) {
if (it->second == nullptr) {
return nullptr;
}
it->second->AttemptAcquire(this);
return it->second.GetRefPtr();
}
return nullptr;
}

View File

@ -568,12 +568,12 @@ bool DBinderDatabusInvoker::OnDatabusSessionClosed(std::shared_ptr<Session> sess
std::u16string descriptor = current->MakeHandleDescriptor(*it);
IRemoteObject *remoteObject = current->QueryObject(descriptor);
if (remoteObject != nullptr) {
(void)current->ProxyDetachDBinderSession(*it);
(void)current->DetachHandleToIndex(*it);
IPCObjectProxy *remoteProxy = reinterpret_cast<IPCObjectProxy *>(remoteObject);
if (remoteProxy->IsSubscribeDeathNotice()) {
remoteProxy->SendObituary();
}
(void)current->ProxyDetachDBinderSession(*it);
(void)current->DetachHandleToIndex(*it);
}
}