1049e185fSopenharmony_ci/* 2049e185fSopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3049e185fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4049e185fSopenharmony_ci * you may not use this file except in compliance with the License. 5049e185fSopenharmony_ci * You may obtain a copy of the License at 6049e185fSopenharmony_ci * 7049e185fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8049e185fSopenharmony_ci * 9049e185fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10049e185fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11049e185fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12049e185fSopenharmony_ci * See the License for the specific language governing permissions and 13049e185fSopenharmony_ci * limitations under the License. 14049e185fSopenharmony_ci */ 15049e185fSopenharmony_ci 16049e185fSopenharmony_ci#include "player_xcollie.h" 17049e185fSopenharmony_ci#include <unistd.h> 18049e185fSopenharmony_ci#include "media_errors.h" 19049e185fSopenharmony_ci#include "media_log.h" 20049e185fSopenharmony_ci#include "param_wrapper.h" 21049e185fSopenharmony_ci#ifdef HICOLLIE_ENABLE 22049e185fSopenharmony_ci#include "xcollie/xcollie.h" 23049e185fSopenharmony_ci#include "xcollie/xcollie_define.h" 24049e185fSopenharmony_ci#endif 25049e185fSopenharmony_ci 26049e185fSopenharmony_cinamespace { 27049e185fSopenharmony_ciconstexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "PlayerXCollie"}; 28049e185fSopenharmony_ci} 29049e185fSopenharmony_ci 30049e185fSopenharmony_cinamespace OHOS { 31049e185fSopenharmony_cinamespace Media { 32049e185fSopenharmony_ciPlayerXCollie &PlayerXCollie::GetInstance() 33049e185fSopenharmony_ci{ 34049e185fSopenharmony_ci static PlayerXCollie instance; 35049e185fSopenharmony_ci return instance; 36049e185fSopenharmony_ci} 37049e185fSopenharmony_ci 38049e185fSopenharmony_ciPlayerXCollie::~PlayerXCollie() 39049e185fSopenharmony_ci{ 40049e185fSopenharmony_ci MEDIA_LOGI("~PlayerXCollie()"); 41049e185fSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 42049e185fSopenharmony_ci#ifdef HICOLLIE_ENABLE 43049e185fSopenharmony_ci for (const auto &iter : dfxDumper_) { 44049e185fSopenharmony_ci HiviewDFX::XCollie::GetInstance().CancelTimer(iter.first); 45049e185fSopenharmony_ci } 46049e185fSopenharmony_ci#endif 47049e185fSopenharmony_ci dfxDumper_.clear(); 48049e185fSopenharmony_ci} 49049e185fSopenharmony_ci 50049e185fSopenharmony_civoid PlayerXCollie::TimerCallback(void *data) 51049e185fSopenharmony_ci{ 52049e185fSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 53049e185fSopenharmony_ci threadDeadlockCount_++; 54049e185fSopenharmony_ci MEDIA_LOGE("threadDeadlockCount: %{public}d", threadDeadlockCount_); 55049e185fSopenharmony_ci static constexpr uint32_t threshold = 5; // >5 Restart service 56049e185fSopenharmony_ci if (threadDeadlockCount_ >= threshold) { 57049e185fSopenharmony_ci _exit(-1); 58049e185fSopenharmony_ci } 59049e185fSopenharmony_ci} 60049e185fSopenharmony_ci 61049e185fSopenharmony_ciint32_t PlayerXCollie::Dump(int32_t fd) 62049e185fSopenharmony_ci{ 63049e185fSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 64049e185fSopenharmony_ci std::string dumpString = "------------------XCollieDfx------------------\n"; 65049e185fSopenharmony_ci for (const auto &iter : dfxDumper_) { 66049e185fSopenharmony_ci dumpString += "WaitTask-----"; 67049e185fSopenharmony_ci dumpString += iter.second; 68049e185fSopenharmony_ci dumpString += "-----\n"; 69049e185fSopenharmony_ci } 70049e185fSopenharmony_ci if (fd != -1) { 71049e185fSopenharmony_ci write(fd, dumpString.c_str(), dumpString.size()); 72049e185fSopenharmony_ci dumpString.clear(); 73049e185fSopenharmony_ci } 74049e185fSopenharmony_ci return MSERR_OK; 75049e185fSopenharmony_ci} 76049e185fSopenharmony_ci 77049e185fSopenharmony_ciint32_t PlayerXCollie::SetTimer(const std::string &name, bool recovery, uint32_t timeout) 78049e185fSopenharmony_ci{ 79049e185fSopenharmony_ci#ifdef HICOLLIE_ENABLE 80049e185fSopenharmony_ci auto func = [this](void *data) { 81049e185fSopenharmony_ci this->TimerCallback(data); 82049e185fSopenharmony_ci }; 83049e185fSopenharmony_ci 84049e185fSopenharmony_ci unsigned int flag = HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_NOOP; 85049e185fSopenharmony_ci if (recovery) { 86049e185fSopenharmony_ci flag |= HiviewDFX::XCOLLIE_FLAG_RECOVERY; 87049e185fSopenharmony_ci } 88049e185fSopenharmony_ci int32_t id = HiviewDFX::XCollie::GetInstance().SetTimer(name, timeout, func, this, flag); 89049e185fSopenharmony_ci if (id != HiviewDFX::INVALID_ID) { 90049e185fSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 91049e185fSopenharmony_ci dfxDumper_.emplace(id, name); 92049e185fSopenharmony_ci } 93049e185fSopenharmony_ci return id; 94049e185fSopenharmony_ci#else 95049e185fSopenharmony_ci return -1; 96049e185fSopenharmony_ci#endif 97049e185fSopenharmony_ci} 98049e185fSopenharmony_ci 99049e185fSopenharmony_ciint32_t PlayerXCollie::SetTimerByLog(const std::string &name, uint32_t timeout) 100049e185fSopenharmony_ci{ 101049e185fSopenharmony_ci#ifdef HICOLLIE_ENABLE 102049e185fSopenharmony_ci unsigned int flag = HiviewDFX::XCOLLIE_FLAG_LOG; 103049e185fSopenharmony_ci int32_t id = HiviewDFX::XCollie::GetInstance().SetTimer(name, timeout, nullptr, this, flag); 104049e185fSopenharmony_ci if (id != HiviewDFX::INVALID_ID) { 105049e185fSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 106049e185fSopenharmony_ci dfxDumper_.emplace(id, name); 107049e185fSopenharmony_ci } 108049e185fSopenharmony_ci return id; 109049e185fSopenharmony_ci#else 110049e185fSopenharmony_ci return -1; 111049e185fSopenharmony_ci#endif 112049e185fSopenharmony_ci} 113049e185fSopenharmony_ci 114049e185fSopenharmony_civoid PlayerXCollie::CancelTimer(int32_t id) 115049e185fSopenharmony_ci{ 116049e185fSopenharmony_ci#ifdef HICOLLIE_ENABLE 117049e185fSopenharmony_ci if (id != HiviewDFX::INVALID_ID) { 118049e185fSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 119049e185fSopenharmony_ci if (dfxDumper_.size() == 0) { 120049e185fSopenharmony_ci return; 121049e185fSopenharmony_ci } 122049e185fSopenharmony_ci auto it = dfxDumper_.find(id); 123049e185fSopenharmony_ci if (it != dfxDumper_.end()) { 124049e185fSopenharmony_ci dfxDumper_.erase(it); 125049e185fSopenharmony_ci return HiviewDFX::XCollie::GetInstance().CancelTimer(id); 126049e185fSopenharmony_ci } 127049e185fSopenharmony_ci } 128049e185fSopenharmony_ci#else 129049e185fSopenharmony_ci (void)id; 130049e185fSopenharmony_ci return; 131049e185fSopenharmony_ci#endif 132049e185fSopenharmony_ci} 133049e185fSopenharmony_ci} // namespace Media 134049e185fSopenharmony_ci} // namespace OHOS