Android 线程死锁问题分析

====================================================================================================================================================
|| pid: 333, tid: 333,
|| backtrace:
||     #00 pc 00019d74  /system/lib/libc.so (syscall+28)
||     #01 pc 0001d145  /system/lib/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+88)
||     #02 pc 0006457d  /system/lib/libc.so (NonPI::MutexLockWithTimeout(pthread_mutex_internal_t*, bool, timespec const*)+156)
||     #03 pc 00061185  /vendor/lib/librtk_tvapi.so (VSCControlImpl::RegisterObserver(rtk::tv::api::IVSCControlObserver*)+14)
||     #04 pc 0004409b  /vendor/lib/librtk_tvservice.so (android::TvService::VSC::InitalDatas()+86)
||     #05 pc 00044369  /vendor/lib/librtk_tvservice.so (android::TvService::VSC::VSC(android::sp<android::TvService> const&, int, int, android::sp<android::IVSCClient> const&, unsigned int)+168)
||     #06 pc 0003ab7b  /vendor/lib/librtk_tvservice.so (android::TvService::createVSC(android::sp<android::IVSCClient> const&)+102)
||     #07 pc 00049cd5  /vendor/lib/librtk_tvsystem.so (android::BnTvService::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+704)
||     #08 pc 00029ed7  /system/lib/vndk-28/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+70)
||     #09 pc 0002f2bb  /system/lib/vndk-28/libbinder.so (android::IPCThreadState::executeCommand(int)+410)
||     #10 pc 0002f047  /system/lib/vndk-28/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+106)
||     #11 pc 0002f56f  /system/lib/vndk-28/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+38)
||     #12 pc 000011df  /vendor/bin/tvservice (main+150)
||     #13 pc 0008bbf5  /system/lib/libc.so (__libc_init+48)
||     #14 pc 00001127  /vendor/bin/tvservice (_start_main+46)
||     #15 pc 00000306  <anonymous:b3328000>
|| 
|| 
|| bool VSCControlImpl::RegisterObserver(IVSCControlObserver* pObs)
|| {
||     Mutex::Autolock autoLock(m_obsMutex);
||     if (!pObs) return false;
|| 
||     ObsLstItor itor, itorEnd = m_ObsLst.end();
||     itor = std::find(m_ObsLst.begin(), itorEnd, pObs);
||     if (itor != itorEnd) return false;
||     pObs->AddRef();
||     m_ObsLst.push_back(pObs);
||     return true;
|| }
|| 拿不到 m_obsMutex
||================================================================================================================================================
|| 
|| pid: 333, tid: 2987
|| backtrace:
||     #00 pc 00019d74  /system/lib/libc.so (syscall+28)
||     #01 pc 0001d145  /system/lib/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+88)
||     #02 pc 0006457d  /system/lib/libc.so (NonPI::MutexLockWithTimeout(pthread_mutex_internal_t*, bool, timespec const*)+156)
||     #03 pc 000620a3  /vendor/lib/librtk_tvapi.so (VSCControlImpl::Notify(VSCControl::OBS_EVENT, __VIDEO_WID_T, bool)+30)
||     #04 pc 00061581  /vendor/lib/librtk_tvapi.so (VSCControlImpl::SetWinBlank(__VIDEO_WID_T, int, VIDEO_DDI_WIN_COLOR_T)+68)
||     #05 pc 00081305  /vendor/lib/librtk_tvapi.so (TvDisplayControl::AutoWinBlank::SetInOutRegion(__VIDEO_WID_T, __VIDEO_RECT_T, __VIDEO_RECT_T, VIDEO_DDI_WIN_COLOR_T, _TV_HDR_TYPE, _SIG_RATIO_DESCRIPTION)+252)
||     #06 pc 0007e797  /vendor/lib/librtk_tvapi.so (TvDisplayControlImpl::SetInOutRegion(__VIDEO_WID_T, __VIDEO_RECT_T, __VIDEO_RECT_T, VIDEO_DDI_WIN_COLOR_T, _TV_HDR_TYPE, _SIG_RATIO_DESCRIPTION)+126)
||     #07 pc 00044b61  /vendor/lib/librtk_tvservice.so (android::TvService::VSC::SetInOutRegion(__VIDEO_WID_T, __VIDEO_RECT_T, __VIDEO_RECT_T, VIDEO_DDI_WIN_COLOR_T, _TV_HDR_TYPE, _SIG_RATIO_DESCRIPTION*)+84)
||     #08 pc 00072075  /vendor/lib/librtk_tvsystem.so (android::BnVSC::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+1208)
||     #09 pc 00029ed7  /system/lib/vndk-28/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+70)
||     #10 pc 0002f2bb  /system/lib/vndk-28/libbinder.so (android::IPCThreadState::executeCommand(int)+410)
||     #11 pc 0002f047  /system/lib/vndk-28/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+106)
||     #12 pc 0002f56f  /system/lib/vndk-28/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+38)
||     #13 pc 00043aed  /system/lib/vndk-28/libbinder.so (android::PoolThread::threadLoop()+12)
||     #14 pc 0000bfd3  /system/lib/vndk-sp-28/libutils.so (android::Thread::_threadLoop(void*)+166)
||     #15 pc 00063a05  /system/lib/libc.so (__pthread_start(void*)+22)
||     #16 pc 0001df95  /system/lib/libc.so (__start_thread+22)
||  bool AutoWinBlank::SetInOutRegion(VIDEO_WID_T wId,
||                                    VIDEO_RECT_T inRegion,
||                                    VIDEO_RECT_T outRegion,
||                                    VIDEO_DDI_WIN_COLOR_T color,
||                                    TV_HDR_TYPE HDRType,
||                                    SIG_RATIO_DESCRIPTION sigRatio)
||  {
||      Mutex::Autolock autoLock(&m_statusLock);
||      StateLstItor iter = m_stateLst.find(wId);
||      if (iter == m_stateLst.end())
||          return false;
||  
||      bool bEnaWinBlank = memcmp(&inRegion, &iter->second->inputRegion, sizeof(VIDEO_RECT_T)) != 0 ||
||                          HDRType != iter->second->HDRType;
||  
||      bool bOutputRegionOnly = inRegion.w == 0 || inRegion.h == 0;
||  
||      if (bEnaWinBlank)
||          m_pDisCtrl->SetVSCWinBlank(wId, true, color);
||  
||      if (!bOutputRegionOnly)
||          m_pDisCtrl->SetInputRegion(wId, inRegion, HDRType, sigRatio);
||  
||      m_pDisCtrl->SetOutputRegion(wId, outRegion);
||  
||      if ((!bOutputRegionOnly)
||  #ifdef ENABLE_MHEG5            
||              && ((RtMHEG5IsStarted() == false) ||
||                  ((RtMHEG5IsStarted() == true) && ((RtMHEG5IsVideoActivate() == true) || (RtMHEG5IsIframeActivate() == true))))
||  #endif
||          )
||          m_pDisCtrl->SetVSCWinBlank(wId, false, color);
||  
|| 
|| bool TvDisplayControlImpl::SetVSCWinBlank(VIDEO_WID_T wId, int32_t bOnOff, VIDEO_DDI_WIN_COLOR_T color)
|| {
||     if (m_pVSCCtrl == NULL)
||         return false;
||     return m_pVSCCtrl->SetWinBlank(wId, bOnOff, color);
|| 	
|| 	
|| 	
|| 	
|| 	bool VSCControlImpl::SetWinBlank(VIDEO_WID_T wId, int32_t bOnOff, VIDEO_DDI_WIN_COLOR_T color)
|| {
||     RTD_AP_LOG(RTD_AP_LOG_LEVEL_I, RTD_AP_LOG_MODULE_PERFORMANCE, "%s wId=%d, bOnOff=%d", __FUNCTION__, wId, bOnOff);
|| 
||     if (bOnOff == true)
||         Notify(OBS_EVENT_MUTE, wId, true);==========================《《《《《
|| 
||     if (bOnOff == 0)
||         PERF_RECORD(PERF_RECORD_MODULE_VSC, PERF_RECORD_ID_T5, PERF_RECORD_TYPE_ALL, RECODRD_STATE_START);
||     return RHAL_VSC_SetWinBlank(wId, bOnOff, color) == API_OK;
|| }
|| 
|| }
|| 
|| 
|| bool VSCControlImpl::Notify(OBS_EVENT event, VIDEO_WID_T wId, bool bEnable)
|| {
||     Mutex::Autolock autoLock(m_obsMutex);
|| 	
|| 
|| m_statusLock拿到,但拿不到 m_obsMutex
|| 	
||=====================================================================================================================================================	
|| 	
|| pid: 333, tid: 573
|| backtrace:
||     #00 pc 00019d74  /system/lib/libc.so (syscall+28)
||     #01 pc 0001d145  /system/lib/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+88)
||     #02 pc 0006457d  /system/lib/libc.so (NonPI::MutexLockWithTimeout(pthread_mutex_internal_t*, bool, timespec const*)+156)
||     #03 pc 0008114b  /vendor/lib/librtk_tvapi.so (TvDisplayControl::AutoWinBlank::ResetState(__VIDEO_WID_T)+6)
||     #04 pc 000814e7  /vendor/lib/librtk_tvapi.so (TvDisplayControl::ObserverMgr::VSCObsImpl::ConnectStartNotify(__VIDEO_WID_T, VSC_INPUT_SRC_INFO, VSC_OUTPUT_MODE, _TV_SOURCE, SOURCE_TYPE)+12)
||     #05 pc 00061fc9  /vendor/lib/librtk_tvapi.so (VSCControlImpl::Notify(VSCControl::OBS_EVENT, __VIDEO_WID_T, VSC_INPUT_SRC_INFO, VSC_OUTPUT_MODE, _TV_SOURCE, SOURCE_TYPE)+108)
||     #06 pc 00061ebf  /vendor/lib/librtk_tvapi.so (VSCControlImpl::ConnectInternal(__VIDEO_WID_T, VSC_INPUT_SRC_INFO, VSC_OUTPUT_MODE, _TV_SOURCE, SOURCE_TYPE)+86)
||     #07 pc 00061e37  /vendor/lib/librtk_tvapi.so (VSCControlImpl::TryToConnect(_TV_SOURCE)+130)
||     #08 pc 00062e4b  /vendor/lib/librtk_tvapi.so (VSCControl::ObserverMgr::VFEObsImpl::VFENotify(_VFE_MESSAGE, _TV_SOURCE)+48)
||     #09 pc 0007b0e3  /vendor/lib/librtk_tvapi.so (CTvSourceControl::NotifyVFE(_VFE_MESSAGE, _TV_SOURCE)+78)
||     #10 pc 0007aea3  /vendor/lib/librtk_tvapi.so (CTvSourceControl::ActivateSource(_TV_SOURCE)+138)
||     #11 pc 0007c0ad  /vendor/lib/librtk_tvapi.so (CTvSourceControl::ChangeSource(_TV_SOURCE, _TV_SOURCE)+164)
||     #12 pc 0007d135  /vendor/lib/librtk_tvapi.so (CTvSourceControl::LooperMgr::onMessageReceived(android::sp<android::RTMessage> const&)+552)
||     #13 pc 0007cee1  /vendor/lib/librtk_tvapi.so (android::RTHandlerReflector<CTvSourceControl::LooperMgr>::onMessageReceived(android::sp<android::RTMessage> const&)+48)
||     #14 pc 00007785  /vendor/lib/librtk_foundation.so (android::RTHandler::deliverMessage(android::sp<android::RTMessage> const&)+24)
||     #15 pc 000094e5  /vendor/lib/librtk_foundation.so (android::RTMessage::deliver()+60)
||     #16 pc 00007d75  /vendor/lib/librtk_foundation.so (android::RTLooper::loop()+328)
||     #17 pc 0000c04b  /system/lib/vndk-sp-28/libutils.so (android::Thread::_threadLoop(void*)+286)
||     #18 pc 00063a05  /system/lib/libc.so (__pthread_start(void*)+22)
||     #19 pc 0001df95  /system/lib/libc.so (__start_thread+22)
|| 	
|| 	bool VSCControlImpl::TryToConnect(TV_SOURCE tvSrc)
|| {
||     Mutex::Autolock autoLock(m_tryToConnectMutex);
|| 
||     INPUT_INFO inputInfo;
||     memset(&inputInfo, 0, sizeof(INPUT_INFO));
|| 
||     for (int i = VIDEO_WID_0 ; i <= VIDEO_WID_1 ; i++)
||     {
||         if (m_statusMgr.GetTempVSCInfo((VIDEO_WID_T)i, m_pResourceClientCallbackImpl)->GetConnected())
||         {
||             m_statusMgr.GetTempVSCInfo((VIDEO_WID_T)i, m_pResourceClientCallbackImpl)->GetInputInfo(&inputInfo);
||             if (memcmp(&inputInfo.tvSrc, &tvSrc, sizeof(TV_SOURCE)) == 0)
||                 ConnectInternal((VIDEO_WID_T)i, inputInfo.vscInput, inputInfo.outputMode, inputInfo.tvSrc, inputInfo.srcType);
||         }
||     }
||     return true;
|| }
|| 
|| bool VSCControlImpl::ConnectInternal(VIDEO_WID_T wId, VSC_INPUT_SRC_INFO_T vscInput, VSC_OUTPUT_MODE_T outputmode, TV_SOURCE tvSrc, SOURCE_TYPE srcType)
|| {
||     Mutex::Autolock autoLock(m_connectInternalMutex);
|| 
||     if (m_statusMgr.GetVSCInfo(wId, m_pResourceClientCallbackImpl)->GetConnected())
||         return false;
|| 
||     Notify(OBS_EVENT_CONNECT_START, wId, vscInput, outputmode, tvSrc, srcType);
|| 
||     AcquireVdec(wId, tvSrc);
||     RHAL_VSC_Open(wId);
||     RHAL_VSC_Connect(wId, vscInput, outputmode);
|| 
||     INPUT_INFO inputInfo;
||     memset(&inputInfo, 0, sizeof(INPUT_INFO));
||     inputInfo.vscInput = vscInput;
||     inputInfo.outputMode = outputmode;
||     inputInfo.tvSrc = tvSrc;
||     inputInfo.srcType = srcType;
||     m_statusMgr.GetVSCInfo(wId, m_pResourceClientCallbackImpl)->SetInputInfo(&inputInfo);
||     m_statusMgr.GetVSCInfo(wId, m_pResourceClientCallbackImpl)->SetConnected(true);
|| 
||     Notify(OBS_EVENT_CONNECT_END, wId, vscInput, outputmode, tvSrc, srcType);
||     return true;
|| }
|| 
|| 
|| bool VSCControlImpl::Notify(OBS_EVENT event, 
||                             VIDEO_WID_T wId, 
||                             VSC_INPUT_SRC_INFO_T vscInput, 
||                             VSC_OUTPUT_MODE_T outputmode, 
||                             TV_SOURCE tvSrc, 
||                             SOURCE_TYPE srcType)
|| {
||     Mutex::Autolock autoLock(m_obsMutex);
||     if (m_ObsLst.size() <= 0)
||         return false;
|| 
||     for (ObsLstItor itor = m_ObsLst.begin() ; itor != m_ObsLst.end() ; ++itor)
||     {
||         switch(event)
||         {
||             case OBS_EVENT_CONNECT_START:
||                 (*itor)->ConnectStartNotify(wId, vscInput, outputmode, tvSrc, srcType);
||                 break;
|| 
|| 
||         bool ConnectStartNotify(VIDEO_WID_T wId, VSC_INPUT_SRC_INFO_T vscInput, VSC_OUTPUT_MODE_T outputmode, TV_SOURCE tvSrc, SOURCE_TYPE srcType)
||         {
||             m_pOutClass->m_pDisCtrl->AutoWinBlankResetState(wId);
||             return true;
||         }
|| 		
|| 		
|| 		void TvDisplayControlImpl::AutoWinBlankResetState(VIDEO_WID_T wId)
|| {
||     if (m_pAutoWinBlank != NULL)
||         m_pAutoWinBlank->ResetState(wId);
|| }
|| 
|| 
|| void AutoWinBlank::ResetState(VIDEO_WID_T wId)
|| {
||     Mutex::Autolock autoLock(&m_statusLock);//wait
||     StateLstItor iter = m_stateLst.find(wId);
||     if (iter == m_stateLst.end())
||         return;
|| 
||     iter->second->inputRegion = {0, 0, 0, 0};
||     iter->second->outputRegion = {0, 0, 0, 0};
||     iter->second->sigRatio = {SIG_RATIO_TYPE_NULL, SIG_ASPECT_RATIO_1_1, 0};
||     iter->second->HDRType = TV_HDR_TYPE_NORMAL;
|| }
|| 
|| m_obsMutex拿到,但拿不到m_statusLock
||==================================================================================================================================================
|| 
||    status
||  A  get m_statusLock  ----> wait m_obsMutex
||  B  get m_obsMutex    ----> wait m_statusLock
|| 
|| 所以两个线程一直在无限等待
|| 
|| 
|| 修改方法,采用tryLock机制。
|| 
|| static const int LockRetries = 30
|| static const int LockSleepUs = 20000
|| static bool tryLock(Mutex& m_statusLock)
|| {
||     bool locked = false;
||     for (int i = 0; i < kDumpLockRetries; ++i) {
||         if (m_statusLock.tryLock() == NO_ERROR) {
||             locked = true;
||             break;
||         }
||         usleep(kDumpLockSleepUs);
||     }
||     return locked;
|| }
|| 
|| 
|| void AutoWinBlank::ResetState(VIDEO_WID_T wId)
|| {
||     //Mutex::Autolock autoLock(&m_statusLock);
||     bool locked = tryLock(m_statusLock);
||     StateLstItor iter = m_stateLst.find(wId);
||     if (iter == m_stateLst.end())
||         return;
|| 
||     iter->second->inputRegion = {0, 0, 0, 0};
||     iter->second->outputRegion = {0, 0, 0, 0};
||     iter->second->sigRatio = {SIG_RATIO_TYPE_NULL, SIG_ASPECT_RATIO_1_1, 0};
||     iter->second->HDRType = TV_HDR_TYPE_NORMAL;
||     if (locked) m_statusLock.unlock();
|| }
||=====================

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值