From 8371c011a694e9e7648cde2312fc57dcad59a7d5 Mon Sep 17 00:00:00 2001 From: "xiaocong.ran" Date: Tue, 19 Apr 2022 10:32:23 +0800 Subject: [PATCH] timer Signed-off-by: xiaocong.ran --- .../include/authentication/dm_auth_manager.h | 2 +- .../include/dependency/timer/dm_timer.h | 110 +++----- .../devicestate/dm_device_state_manager.h | 2 +- .../include/discovery/dm_discovery_manager.h | 2 +- .../src/authentication/dm_auth_manager.cpp | 92 ++---- .../src/dependency/timer/dm_timer.cpp | 264 +++++++++--------- .../devicestate/dm_device_state_manager.cpp | 35 ++- .../src/discovery/dm_discovery_manager.cpp | 15 +- 8 files changed, 229 insertions(+), 293 deletions(-) diff --git a/services/devicemanagerservice/include/authentication/dm_auth_manager.h b/services/devicemanagerservice/include/authentication/dm_auth_manager.h index a463dbf3f..700c965fd 100644 --- a/services/devicemanagerservice/include/authentication/dm_auth_manager.h +++ b/services/devicemanagerservice/include/authentication/dm_auth_manager.h @@ -384,7 +384,7 @@ private: std::shared_ptr authRequestContext_; std::shared_ptr authResponseContext_; std::shared_ptr authMessageProcessor_; - std::map> timerMap_; + std::shared_ptr timerHeap_; std::shared_ptr dmAbilityMgr_; bool isCryptoSupport_ = false; bool isFinishOfLocal_ = true; diff --git a/services/devicemanagerservice/include/dependency/timer/dm_timer.h b/services/devicemanagerservice/include/dependency/timer/dm_timer.h index 27def3ae2..3d202ea5e 100644 --- a/services/devicemanagerservice/include/dependency/timer/dm_timer.h +++ b/services/devicemanagerservice/include/dependency/timer/dm_timer.h @@ -15,89 +15,51 @@ #ifndef TIMER_H #define TIMER_H + +#include #include -#include +#include +#include #include -#if !defined(__LITEOS_M__) #include -#include -#include -#include -#endif -#include -#include - -#include "dm_log.h" +#include +#include namespace OHOS { namespace DistributedHardware { -class DmTimer; -typedef void (*TimeoutHandle)(void *data, DmTimer& timer); - -#define MAX_EVENTS 255 - -enum DmTimerStatus : int32_t { - DM_STATUS_INIT = 0, - DM_STATUS_RUNNING = 1, - DM_STATUS_BUSY = 2, - DM_STATUS_CREATE_ERROR = 3, - DM_STATUS_FINISH = 6, -}; - +typedef void (*TimeoutHandle)(void *data, std::string timerName); class DmTimer { public: - explicit DmTimer(const std::string &name); - ~DmTimer(); - - /** - * @tc.name: DmTimer::Start - * @tc.desc: Start of the DmTimer - * @tc.type: FUNC - */ - DmTimerStatus Start(uint32_t timeOut, TimeoutHandle handle, void *data); - - /** - * @tc.name: DmTimer::Stop - * @tc.desc: Stop of the DmTimer - * @tc.type: FUNC - */ - void Stop(int32_t code); - - /** - * @tc.name: DmTimer::WaitForTimeout - * @tc.desc: WaitFor Timeout of the DmTimer - * @tc.type: FUNC - */ - void WaitForTimeout(); - - /** - * @tc.name: DmTimer::GetTimerName - * @tc.desc: Get TimerName of the DmTimer - * @tc.type: FUNC - */ - std::string GetTimerName(); -private: - int32_t CreateTimeFd(); - void Release(); + DmTimer(std::string name, time_t expire, void *user, TimeoutHandle mHandle) + :userData_(user), timerName_(name), expire_(expire), mHandle_(mHandle) {}; +public: + void *userData_; + bool isTrigger = false; + std::string timerName_; + time_t expire_; + TimeoutHandle mHandle_;; +}; +class TimeHeap { +public: + TimeHeap(); + int32_t AddTimer(std::string name, int timeout, TimeoutHandle mHandle, void *user); + int32_t DelTimer(std::string name); + int32_t DelAll(); + int32_t Tick(); +private: + void CheckSize(); + void MoveUp(std::shared_ptr timer); + void Run(); private: - DmTimerStatus mStatus_; - uint32_t mTimeOutSec_; - TimeoutHandle mHandle_; - void *mHandleData_; - int32_t mTimeFd_[2]; -#if defined(__LITEOS_M__) - void *timerId = NULL; -#else - struct epoll_event mEv_; - struct epoll_event mEvents_[MAX_EVENTS]; - int32_t mEpFd_; + const int32_t INIT_SIZE = 50; + const int32_t MAX_EVENT_NUMBER = 10; + int32_t hsize_ = 0; + int32_t epollFd_; + int32_t pipefd[2]; std::thread mThread_; - std::mutex mTimerLock_; -#endif - - std::string mTimerName_; + std::vector> minHeap_; }; -} // namespace DistributedHardware -} // namespace OHOS -#endif // TIMER_H +} +} +#endif \ No newline at end of file diff --git a/services/devicemanagerservice/include/devicestate/dm_device_state_manager.h b/services/devicemanagerservice/include/devicestate/dm_device_state_manager.h index 2cf315b82..95a59c511 100755 --- a/services/devicemanagerservice/include/devicestate/dm_device_state_manager.h +++ b/services/devicemanagerservice/include/devicestate/dm_device_state_manager.h @@ -36,7 +36,6 @@ struct StateTimerInfo { std::string timerName; std::string netWorkId; std::string deviceId; - std::shared_ptr timer; }; class DmDeviceStateManager final : public ISoftbusStateCallback, @@ -164,6 +163,7 @@ private: std::map remoteDeviceInfos_; std::map decisionInfos_; std::map stateTimerInfoMap_; + std::shared_ptr timerHeap_; std::shared_ptr hiChainConnector_; std::string decisionSoName_; }; diff --git a/services/devicemanagerservice/include/discovery/dm_discovery_manager.h b/services/devicemanagerservice/include/discovery/dm_discovery_manager.h index db0e97d28..00e756b36 100644 --- a/services/devicemanagerservice/include/discovery/dm_discovery_manager.h +++ b/services/devicemanagerservice/include/discovery/dm_discovery_manager.h @@ -84,7 +84,7 @@ private: std::shared_ptr listener_; std::queue discoveryQueue_; std::map discoveryContextMap_; - std::shared_ptr discoveryTimer_; + std::shared_ptr timerHeap_; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/devicemanagerservice/src/authentication/dm_auth_manager.cpp b/services/devicemanagerservice/src/authentication/dm_auth_manager.cpp index 86d31b3e7..79f9153a9 100644 --- a/services/devicemanagerservice/src/authentication/dm_auth_manager.cpp +++ b/services/devicemanagerservice/src/authentication/dm_auth_manager.cpp @@ -30,7 +30,6 @@ namespace OHOS { namespace DistributedHardware { -const int32_t SESSION_CANCEL_TIMEOUT = 0; const int32_t AUTHENTICATE_TIMEOUT = 120; const int32_t CONFIRM_TIMEOUT = 60; const int32_t NEGOTIATE_TIMEOUT = 10; @@ -41,10 +40,10 @@ const int32_t WAIT_REQUEST_TIMEOUT = 10; const int32_t CANCEL_PIN_CODE_DISPLAY = 1; const int32_t DEVICE_ID_HALF = 2; -static void TimeOut(void *data, DmTimer& timer) +static void TimeOut(void *data, std::string timerName) { - LOGI("time out %s", timer.GetTimerName().c_str()); - if (data == nullptr || timer.GetTimerName().find(TIMER_PREFIX) != TIMER_DEFAULT) { + LOGI("time out %s", timerName.c_str()); + if (data == nullptr || timerName.find(TIMER_PREFIX) != TIMER_DEFAULT) { LOGE("time out is not our timer"); return; } @@ -131,9 +130,10 @@ int32_t DmAuthManager::AuthenticateDevice(const std::string &pkgName, int32_t au authRequestState_->SetAuthManager(shared_from_this()); authRequestState_->SetAuthContext(authRequestContext_); authRequestState_->Enter(); - std::shared_ptr authenticateStartTimer = std::make_shared(AUTHENTICATE_TIMEOUT_TASK); - timerMap_[AUTHENTICATE_TIMEOUT_TASK] = authenticateStartTimer; - authenticateStartTimer->Start(AUTHENTICATE_TIMEOUT, TimeOut, this); + if (timerHeap_ == nullptr) { + timerHeap_ = std::make_shared(); + } + timerHeap_->AddTimer(AUTHENTICATE_TIMEOUT_TASK, AUTHENTICATE_TIMEOUT, TimeOut, this); LOGI("DmAuthManager::AuthenticateDevice complete"); return DM_OK; } @@ -174,12 +174,11 @@ int32_t DmAuthManager::VerifyAuthentication(const std::string &authParam) return DM_AUTH_NOT_START; } std::shared_ptr ptr; - if (authenticationMap_.find(authResponseContext_->authType) == authenticationMap_.end() - || timerMap_.find(INPUT_TIMEOUT_TASK) == timerMap_.end()) { + if (authenticationMap_.find(authResponseContext_->authType) == authenticationMap_.end()) { LOGE("DmAuthManager::authenticationMap_ is null"); return DM_FAILED; } - timerMap_[INPUT_TIMEOUT_TASK]->Stop(SESSION_CANCEL_TIMEOUT); + timerHeap_->DelTimer(INPUT_TIMEOUT_TASK); ptr = authenticationMap_[authResponseContext_->authType]; int32_t ret = ptr->VerifyAuthentication(authResponseContext_->authToken, authParam); switch (ret) { @@ -210,12 +209,9 @@ void DmAuthManager::OnSessionOpened(int32_t sessionId, int32_t sessionSide, int3 authResponseState_->SetAuthManager(shared_from_this()); authResponseState_->Enter(); authResponseContext_ = std::make_shared(); - std::shared_ptr waitStartTimer = std::make_shared(WAIT_NEGOTIATE_TIMEOUT_TASK); - timerMap_[WAIT_NEGOTIATE_TIMEOUT_TASK] = waitStartTimer; - waitStartTimer->Start(WAIT_NEGOTIATE_TIMEOUT, TimeOut, this); - std::shared_ptr authenticateStartTimer = std::make_shared(AUTHENTICATE_TIMEOUT_TASK); - timerMap_[AUTHENTICATE_TIMEOUT_TASK] = authenticateStartTimer; - authenticateStartTimer->Start(AUTHENTICATE_TIMEOUT, TimeOut, this); + timerHeap_ = std::make_shared(); + timerHeap_->AddTimer(AUTHENTICATE_TIMEOUT_TASK, AUTHENTICATE_TIMEOUT, TimeOut, this); + timerHeap_->AddTimer(WAIT_NEGOTIATE_TIMEOUT_TASK, WAIT_NEGOTIATE_TIMEOUT, TimeOut, this); } else { std::shared_ptr authMessageProcessor = std::make_shared(shared_from_this()); @@ -294,18 +290,16 @@ void DmAuthManager::OnDataReceived(const int32_t sessionId, const std::string me switch (authResponseContext_->msgType) { case MSG_TYPE_NEGOTIATE: - if (authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_INIT - && timerMap_.find(WAIT_NEGOTIATE_TIMEOUT_TASK) != timerMap_.end()) { - timerMap_[WAIT_NEGOTIATE_TIMEOUT_TASK]->Stop(SESSION_CANCEL_TIMEOUT); + if (authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_INIT) { + timerHeap_->DelTimer(WAIT_NEGOTIATE_TIMEOUT_TASK); authResponseState_->TransitionTo(std::make_shared()); } else { LOGE("Device manager auth state error"); } break; case MSG_TYPE_REQ_AUTH: - if (authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_NEGOTIATE - && timerMap_.find(WAIT_REQUEST_TIMEOUT_TASK) != timerMap_.end()) { - timerMap_[WAIT_REQUEST_TIMEOUT_TASK]->Stop(SESSION_CANCEL_TIMEOUT); + if (authResponseState_->GetStateType() == AuthState::AUTH_RESPONSE_NEGOTIATE) { + timerHeap_->DelTimer(WAIT_REQUEST_TIMEOUT_TASK); authResponseState_->TransitionTo(std::make_shared()); } else { LOGE("Device manager auth state error"); @@ -359,8 +353,8 @@ void DmAuthManager::OnGroupCreated(int64_t requestId, const std::string &groupId void DmAuthManager::OnMemberJoin(int64_t requestId, int32_t status) { LOGI("DmAuthManager OnMemberJoin start"); - if (authRequestState_ != nullptr && timerMap_.find(ADD_TIMEOUT_TASK) != timerMap_.end()) { - timerMap_[ADD_TIMEOUT_TASK]->Stop(SESSION_CANCEL_TIMEOUT); + if (authRequestState_ != nullptr) { + timerHeap_->DelTimer(ADD_TIMEOUT_TASK); if (status != DM_OK || authResponseContext_->requestId != requestId) { if (authRequestState_ != nullptr) { authResponseContext_->state = AuthState::AUTH_REQUEST_JOIN; @@ -419,9 +413,7 @@ void DmAuthManager::StartNegotiate(const int32_t &sessionId) authMessageProcessor_->SetResponseContext(authResponseContext_); std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_NEGOTIATE); softbusConnector_->GetSoftbusSession()->SendData(sessionId, message); - std::shared_ptr negotiateStartTimer = std::make_shared(NEGOTIATE_TIMEOUT_TASK); - timerMap_[NEGOTIATE_TIMEOUT_TASK] = negotiateStartTimer; - negotiateStartTimer->Start(NEGOTIATE_TIMEOUT, TimeOut, this); + timerHeap_->AddTimer(NEGOTIATE_TIMEOUT_TASK, NEGOTIATE_TIMEOUT, TimeOut, this); } void DmAuthManager::RespNegotiate(const int32_t &sessionId) @@ -460,18 +452,13 @@ void DmAuthManager::RespNegotiate(const int32_t &sessionId) jsonObject[TAG_CRYPTO_SUPPORT] = "false"; message = jsonObject.dump(); softbusConnector_->GetSoftbusSession()->SendData(sessionId, message); - std::shared_ptr waitStartTimer = std::make_shared(WAIT_REQUEST_TIMEOUT_TASK); - timerMap_[WAIT_REQUEST_TIMEOUT_TASK] = waitStartTimer; - waitStartTimer->Start(WAIT_REQUEST_TIMEOUT, TimeOut, this); + timerHeap_->AddTimer(WAIT_REQUEST_TIMEOUT_TASK, WAIT_REQUEST_TIMEOUT, TimeOut, this); } void DmAuthManager::SendAuthRequest(const int32_t &sessionId) { LOGI("DmAuthManager::EstablishAuthChannel session id"); - if (timerMap_.find(NEGOTIATE_TIMEOUT_TASK) == timerMap_.end()) { - return; - } - timerMap_[NEGOTIATE_TIMEOUT_TASK]->Stop(SESSION_CANCEL_TIMEOUT); + timerHeap_->DelTimer(NEGOTIATE_TIMEOUT_TASK); if (authResponseContext_->cryptoSupport) { isCryptoSupport_ = true; } @@ -483,9 +470,7 @@ void DmAuthManager::SendAuthRequest(const int32_t &sessionId) for (auto msg : messageList) { softbusConnector_->GetSoftbusSession()->SendData(sessionId, msg); } - std::shared_ptr confirmStartTimer = std::make_shared(CONFIRM_TIMEOUT_TASK); - timerMap_[CONFIRM_TIMEOUT_TASK] = confirmStartTimer; - confirmStartTimer->Start(CONFIRM_TIMEOUT, TimeOut, this); + timerHeap_->AddTimer(CONFIRM_TIMEOUT_TASK, CONFIRM_TIMEOUT, TimeOut, this); } int32_t DmAuthManager::StartAuthProcess(const int32_t &action) @@ -511,15 +496,9 @@ int32_t DmAuthManager::StartAuthProcess(const int32_t &action) void DmAuthManager::StartRespAuthProcess() { LOGI("DmAuthManager::StartRespAuthProcess", authResponseContext_->sessionId); - if (timerMap_.find(CONFIRM_TIMEOUT_TASK) == timerMap_.end()) { - return; - } - - timerMap_[CONFIRM_TIMEOUT_TASK]->Stop(SESSION_CANCEL_TIMEOUT); + timerHeap_->DelTimer(CONFIRM_TIMEOUT_TASK); if (authResponseContext_->reply == USER_OPERATION_TYPE_ALLOW_AUTH) { - std::shared_ptr inputStartTimer = std::make_shared(INPUT_TIMEOUT_TASK); - timerMap_[INPUT_TIMEOUT_TASK] = inputStartTimer; - inputStartTimer->Start(INPUT_TIMEOUT, TimeOut, this); + timerHeap_->AddTimer(INPUT_TIMEOUT_TASK, INPUT_TIMEOUT, TimeOut, this); authRequestState_->TransitionTo(std::make_shared()); } else { LOGE("do not accept"); @@ -555,9 +534,7 @@ int32_t DmAuthManager::AddMember(const std::string &deviceId) jsonObject[TAG_REQUEST_ID] = authResponseContext_->requestId; jsonObject[TAG_DEVICE_ID] = authResponseContext_->deviceId; std::string connectInfo = jsonObject.dump(); - std::shared_ptr joinStartTimer = std::make_shared(ADD_TIMEOUT_TASK); - timerMap_[ADD_TIMEOUT_TASK] = joinStartTimer; - joinStartTimer->Start(ADD_TIMEOUT, TimeOut, this); + timerHeap_->AddTimer(ADD_TIMEOUT_TASK, ADD_TIMEOUT, TimeOut, this); int32_t ret = hiChainConnector_->AddMember(deviceId, connectInfo); if (ret != 0) { return DM_FAILED; @@ -584,10 +561,7 @@ std::string DmAuthManager::GetConnectAddr(std::string deviceId) int32_t DmAuthManager::JoinNetwork() { LOGI("DmAuthManager JoinNetwork start"); - if (timerMap_.find(AUTHENTICATE_TIMEOUT_TASK) == timerMap_.end()) { - return DM_FAILED; - } - timerMap_[AUTHENTICATE_TIMEOUT_TASK]->Stop(SESSION_CANCEL_TIMEOUT); + timerHeap_->DelTimer(AUTHENTICATE_TIMEOUT_TASK); authResponseContext_->state = AuthState::AUTH_REQUEST_FINISH; authRequestContext_->reason = DM_OK; authRequestState_->TransitionTo(std::make_shared()); @@ -612,12 +586,7 @@ void DmAuthManager::AuthenticateFinish() std::string message = authMessageProcessor_->CreateSimpleMessage(MSG_TYPE_REQ_AUTH_TERMINATE); softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message); } - if (!timerMap_.empty()) { - for (auto &iter : timerMap_) { - iter.second->Stop(SESSION_CANCEL_TIMEOUT); - } - timerMap_.clear(); - } + timerHeap_->DelAll(); isFinishOfLocal_ = true; authResponseContext_ = nullptr; authResponseState_ = nullptr; @@ -642,12 +611,7 @@ void DmAuthManager::AuthenticateFinish() listener_->OnAuthResult(authRequestContext_->hostPkgName, authRequestContext_->deviceId, authRequestContext_->token, authResponseContext_->state, authRequestContext_->reason); softbusConnector_->GetSoftbusSession()->CloseAuthSession(authRequestContext_->sessionId); - if (!timerMap_.empty()) { - for (auto &iter : timerMap_) { - iter.second->Stop(SESSION_CANCEL_TIMEOUT); - } - timerMap_.clear(); - } + timerHeap_->DelAll(); isFinishOfLocal_ = true; authRequestContext_ = nullptr; authResponseContext_ = nullptr; diff --git a/services/devicemanagerservice/src/dependency/timer/dm_timer.cpp b/services/devicemanagerservice/src/dependency/timer/dm_timer.cpp index d103e8822..0ee67ebb7 100644 --- a/services/devicemanagerservice/src/dependency/timer/dm_timer.cpp +++ b/services/devicemanagerservice/src/dependency/timer/dm_timer.cpp @@ -13,177 +13,189 @@ * limitations under the License. */ -#include "dm_timer.h" - -#include - #include "dm_constants.h" -#include "securec.h" +#include "dm_log.h" +#include "dm_timer.h" namespace OHOS { namespace DistributedHardware { -namespace { -const int32_t MILL_SECONDS_PER_SECOND = 1000; +void TimeHeap::CheckSize() +{ + if(hsize_ == (int32_t)(minHeap_.size() - 1)) + { + minHeap_.resize(2 * minHeap_.size()); + } } -DmTimer::DmTimer(const std::string &name) +void TimeHeap::MoveUp(std::shared_ptr timer) { - if (name.empty() || name.find(TIMER_PREFIX) != TIMER_DEFAULT) { - LOGE("DmTimer name is null"); - mTimerName_ = ""; + if (timer == nullptr) { + LOGE("MoveUp timer is null"); return; } - mStatus_ = DmTimerStatus::DM_STATUS_INIT; - mTimeOutSec_ = 0; - mHandle_ = nullptr; - mHandleData_ = nullptr; - (void)memset_s(mTimeFd_, sizeof(mTimeFd_), 0, sizeof(mTimeFd_)); - (void)memset_s(&mEv_, sizeof(mEv_), 0, sizeof(mEv_)); - (void)memset_s(mEvents_, sizeof(mEvents_), 0, sizeof(mEvents_)); - mEpFd_ = 0; - mTimerName_ = name; -} - -DmTimer::~DmTimer() -{ - if (mTimerName_.empty() || mTimerName_.find(TIMER_PREFIX) != TIMER_DEFAULT) { - LOGE("DmTimer is not init"); + if (hsize_ == 0) { + LOGE("Add timer failed"); return; } - LOGI("DmTimer %s destroy in", mTimerName_.c_str()); - Stop(0); - std::lock_guard lock(mTimerLock_); - Release(); + for (int32_t i = 1;; i++) { + LOGE("MoveUp 1 = %d, h = %d", i, hsize_); + if (i == hsize_) { + minHeap_.insert(minHeap_.begin() + (i - 1), timer); + break; + } + if (timer->expire_ < minHeap_[i - 1]->expire_) { + minHeap_.insert(minHeap_.begin() + (i -1), timer); + break; + } + } } -DmTimerStatus DmTimer::Start(uint32_t timeOut, TimeoutHandle handle, void *data) +void TimeHeap::Run() { - if (mTimerName_.empty() || mTimerName_.find(TIMER_PREFIX) != TIMER_DEFAULT || handle == nullptr || - data == nullptr) { - LOGE("DmTimer is not init or param empty"); - return DmTimerStatus::DM_STATUS_FINISH; - } + epoll_event event; + event.data.fd = pipefd[0]; + event.events = EPOLLIN | EPOLLET; + epoll_ctl(epollFd_, EPOLL_CTL_ADD, pipefd[0], &event); + epoll_event events[MAX_EVENT_NUMBER]; + bool stop = false; + int timeout = -1; + + while(!stop) + { + int number = epoll_wait(epollFd_, events, MAX_EVENT_NUMBER, timeout); + + LOGI("RunTimer is doing"); + if (number < 0) { + LOGE("DmTimer %s epoll_wait error: %d", minHeap_.front()->timerName_.c_str(), errno); + DelTimer(minHeap_.front()->timerName_); + break; + } + if(!number) { + timeout = Tick(); + } else { + int buffer = 0; + recv(pipefd[0], (char*)&buffer, sizeof(buffer), 0); + timeout = hsize_ ? -1 : minHeap_.front()->expire_ - time(NULL); + } - LOGI("DmTimer %s start timeout(%d)", mTimerName_.c_str(), timeOut); - if (mStatus_ != DmTimerStatus::DM_STATUS_INIT) { - return DmTimerStatus::DM_STATUS_BUSY; + if (timeout == -1) { + break; + } else { + timeout *= 1000; + } } +} - mTimeOutSec_ = timeOut; - mHandle_ = handle; - mHandleData_ = data; +TimeHeap::TimeHeap(): hsize_(0), epollFd_(epoll_create(5)) +{ + minHeap_.resize(INIT_SIZE); - if (CreateTimeFd()) { - return DmTimerStatus::DM_STATUS_CREATE_ERROR; + int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd); + if (ret != 0) { + LOGE("open pipe failed"); } - - mStatus_ = DmTimerStatus::DM_STATUS_RUNNING; - mThread_ = std::thread(&DmTimer::WaitForTimeout, this); - mThread_.detach(); - return mStatus_; + assert(ret == 0); } -void DmTimer::Stop(int32_t code) +int32_t TimeHeap::AddTimer(std::string name, int timeout, TimeoutHandle mHandle, void *user) { - if (mTimerName_.empty() || mTimerName_.find(TIMER_PREFIX) != TIMER_DEFAULT || mHandleData_ == nullptr) { - LOGE("DmTimer is not init"); - return; + if (name.empty() || name.find(TIMER_PREFIX) != TIMER_DEFAULT) { + LOGE("DmTimer name is not DM timer"); + return DM_INVALID_VALUE; } - if (mTimeFd_[1]) { - char event = 'S'; - if (write(mTimeFd_[1], &event, 1) < 0) { - return; - } + LOGI("AddTimer %s", name.c_str()); + if(timeout <= 0 || mHandle == nullptr || user == nullptr) { + LOGE("DmTimer %s invalid value", name.c_str()); + return DM_INVALID_VALUE; } -} -void DmTimer::WaitForTimeout() -{ - if (mTimerName_.empty() || mTimerName_.find(TIMER_PREFIX) != TIMER_DEFAULT) { - LOGE("DmTimer is not init"); - return; + if (hsize_ == 0) { + mThread_ = std::thread(&TimeHeap::Run, this); + mThread_.detach(); } - LOGI("DmTimer %s start timer at (%d)s", mTimerName_.c_str(), mTimeOutSec_); - std::lock_guard lock(mTimerLock_); - int32_t nfds = epoll_wait(mEpFd_, mEvents_, MAX_EVENTS, mTimeOutSec_ * MILL_SECONDS_PER_SECOND); - LOGI("DmTimer is triggering"); - if (nfds > 0) { - char event = 0; - if (mEvents_[0].events & EPOLLIN) { - int num = read(mTimeFd_[0], &event, 1); - LOGD("DmTimer %s exit with num=%d, event=%d, errno=%d", mTimerName_.c_str(), num, event, errno); - } - } else if (nfds == 0) { - if (mHandleData_ != nullptr) { - mHandle_(mHandleData_, *this); - LOGI("DmTimer %s end timer at (%d)s", mTimerName_.c_str(), mTimeOutSec_); - } - } else { - LOGI("DmTimer %s epoll_wait return nfds=%d, errno=%d", mTimerName_.c_str(), nfds, errno); + CheckSize(); + std::shared_ptr timer = std::make_shared(name, timeout + time(NULL), user, mHandle); + ++hsize_; + MoveUp(timer); + if(timer == minHeap_.front()) { + char msg = 1; + send(pipefd[1], (char*)&msg, sizeof(msg), 0); } - Release(); + LOGE("AddTimer %s complete", name.c_str()); + return DM_OK; } -int32_t DmTimer::CreateTimeFd() +int32_t TimeHeap::DelTimer(std::string name) { - if (mTimerName_.empty() || mTimerName_.find(TIMER_PREFIX) != TIMER_DEFAULT) { - LOGE("DmTimer is not init"); - return DM_STATUS_FINISH; + if (name.empty() || name.find(TIMER_PREFIX) != TIMER_DEFAULT) { + LOGE("DmTimer name is not DM timer"); + return DM_INVALID_VALUE; } - LOGI("DmTimer %s creatTimeFd", mTimerName_.c_str()); - int ret = pipe(mTimeFd_); - if (ret < 0) { - LOGE("DmTimer %s CreateTimeFd fail:(%d) errno(%d)", mTimerName_.c_str(), ret, errno); - return ret; + LOGI("DelTimer %s", name.c_str()); + int32_t location = 0; + bool have = false; + for (int32_t i = 0; i < hsize_; i++) { + if (minHeap_[i]->timerName_ == name) { + location = i; + have = true; + break; + } } - std::lock_guard lock(mTimerLock_); - mEv_.data.fd = mTimeFd_[0]; - mEv_.events = EPOLLIN | EPOLLET; - mEpFd_ = epoll_create(MAX_EVENTS); - ret = epoll_ctl(mEpFd_, EPOLL_CTL_ADD, mTimeFd_[0], &mEv_); - if (ret != 0) { - Release(); + if(!have) { + LOGE("heap is not have this %s", name.c_str()); + return DM_INVALID_VALUE; + } + + if (location == 0 && minHeap_[location]->isTrigger == false) { + char msg = 1; + send(pipefd[1], &msg, sizeof(msg), 0); } - return ret; + minHeap_.erase(minHeap_.begin() + location); + hsize_--; + LOGI("DelTimer %s complete , timer count %d", name.c_str(), hsize_); + return DM_OK; } -void DmTimer::Release() +int32_t TimeHeap::DelAll() { - if (mTimerName_.empty() || mTimerName_.find(TIMER_PREFIX) != TIMER_DEFAULT) { - LOGE("DmTimer is not init"); - return; + LOGI("DelAll start"); + for (int32_t i = hsize_ ; i > 0; i--) { + DelTimer(minHeap_[i - 1]->timerName_); } - LOGI("DmTimer %s release in", mTimerName_.c_str()); + LOGI("DelAll complete"); + return DM_OK; +} - if (mStatus_ == DmTimerStatus::DM_STATUS_INIT) { - LOGE("DmTimer %s already release", mTimerName_.c_str()); - return; - } +int32_t TimeHeap::Tick() +{ + LOGI("Tick start"); + time_t cur_time = time(NULL); - mStatus_ = DmTimerStatus::DM_STATUS_INIT; - close(mTimeFd_[0]); - close(mTimeFd_[1]); - if (mEpFd_ >= 0) { - close(mEpFd_); + if (hsize_ == 0) { + LOGE("Timer count is 0"); + return -1; } - mTimerName_ = ""; - mTimeOutSec_ = 0; - mHandle_ = nullptr; - mHandleData_ = nullptr; - mTimeFd_[0] = 0; - mTimeFd_[1] = 0; - mEpFd_ = 0; -} -std::string DmTimer::GetTimerName() -{ - return mTimerName_; + std::shared_ptr top = minHeap_.front(); + top->isTrigger = true; + do { + top->mHandle_(top->userData_, top->timerName_); + DelTimer(top->timerName_); + + if(hsize_ > 0) { + top = minHeap_.front(); + } else { + break; + } + }while(top->expire_ <= cur_time); + + return hsize_ ? -1 :top->expire_ - cur_time; +} } -} // namespace DistributedHardware -} // namespace OHOS +} \ No newline at end of file diff --git a/services/devicemanagerservice/src/devicestate/dm_device_state_manager.cpp b/services/devicemanagerservice/src/devicestate/dm_device_state_manager.cpp index e8d0d95ad..3d5a55ec6 100755 --- a/services/devicemanagerservice/src/devicestate/dm_device_state_manager.cpp +++ b/services/devicemanagerservice/src/devicestate/dm_device_state_manager.cpp @@ -22,12 +22,10 @@ namespace OHOS { namespace DistributedHardware { -const int32_t SESSION_CANCEL_TIMEOUT = 0; - -static void TimeOut(void *data, DmTimer& timer) +static void TimeOut(void *data, std::string timerName) { - LOGI("time out %s", timer.GetTimerName().c_str()); - if (data == nullptr || timer.GetTimerName().find(TIMER_PREFIX) != TIMER_DEFAULT) { + LOGI("time out %s", timerName.c_str()); + if (data == nullptr || timerName.find(TIMER_PREFIX) != TIMER_DEFAULT) { LOGE("time out is not our timer"); return; } @@ -38,7 +36,7 @@ static void TimeOut(void *data, DmTimer& timer) return; } - deviceStateMgr->DeleteTimeOutGroup(timer.GetTimerName()); + deviceStateMgr->DeleteTimeOutGroup(timerName); } DmDeviceStateManager::DmDeviceStateManager(std::shared_ptr softbusConnector, @@ -278,22 +276,21 @@ void DmDeviceStateManager::RegisterOffLineTimer(const DmDeviceInfo &deviceInfo) #endif for (auto &iter : stateTimerInfoMap_) { if (iter.second.netWorkId == deviceInfo.deviceId) { - iter.second.timer->Stop(SESSION_CANCEL_TIMEOUT); + timerHeap_->DelTimer(iter.second.timerName); return; } } - std::string timerName = TIMER_PREFIX + STATE_TIMER_PREFIX + std::to_string(cumulativeQuantity_++); - std::shared_ptr offLineTimer = std::make_shared(timerName); - if (offLineTimer != nullptr) { - StateTimerInfo stateTimer = { - .timerName = timerName, - .netWorkId = deviceInfo.deviceId, - .deviceId = deviceId, - .timer = offLineTimer - }; - stateTimerInfoMap_[timerName] = stateTimer; + if (timerHeap_ == nullptr) { + timerHeap_ = std::make_shared(); } + std::string timerName = TIMER_PREFIX + STATE_TIMER_PREFIX + std::to_string(cumulativeQuantity_++); + StateTimerInfo stateTimer = { + .timerName = timerName, + .netWorkId = deviceInfo.deviceId, + .deviceId = deviceId, + }; + stateTimerInfoMap_[timerName] = stateTimer; } void DmDeviceStateManager::StartOffLineTimer(const DmDeviceInfo &deviceInfo) @@ -304,9 +301,9 @@ void DmDeviceStateManager::StartOffLineTimer(const DmDeviceInfo &deviceInfo) std::lock_guard mutexLock(timerMapMutex_); #endif LOGI("start offline timer"); - for (auto &iter : stateTimerInfoMap_) { + for (auto &iter : stateTimerInfoMap_) { if (iter.second.netWorkId == deviceInfo.deviceId) { - iter.second.timer->Start(OFFLINE_TIMEOUT, TimeOut, this); + timerHeap_->AddTimer(iter.second.timerName, OFFLINE_TIMEOUT, TimeOut, this); } } } diff --git a/services/devicemanagerservice/src/discovery/dm_discovery_manager.cpp b/services/devicemanagerservice/src/discovery/dm_discovery_manager.cpp index bc8f80ad3..ec0cf6383 100644 --- a/services/devicemanagerservice/src/discovery/dm_discovery_manager.cpp +++ b/services/devicemanagerservice/src/discovery/dm_discovery_manager.cpp @@ -23,12 +23,11 @@ namespace OHOS { namespace DistributedHardware { const std::string DISCOVERY_TIMEOUT_TASK = TIMER_PREFIX + "discovery"; const int32_t DISCOVERY_TIMEOUT = 120; -const int32_t SESSION_CANCEL_TIMEOUT = 0; -static void TimeOut(void *data, DmTimer& timer) +static void TimeOut(void *data, std::string timerName) { - LOGI("time out %s", timer.GetTimerName().c_str()); - if (data == nullptr || timer.GetTimerName() != DISCOVERY_TIMEOUT_TASK) { + LOGI("time out %s", timerName.c_str()); + if (data == nullptr || timerName != DISCOVERY_TIMEOUT_TASK) { LOGE("time out is not our timer"); return; } @@ -72,8 +71,10 @@ int32_t DmDiscoveryManager::StartDeviceDiscovery(const std::string &pkgName, con discoveryContextMap_.emplace(pkgName, context); softbusConnector_->RegisterSoftbusDiscoveryCallback(pkgName, std::shared_ptr(shared_from_this())); - discoveryTimer_ = std::make_shared(DISCOVERY_TIMEOUT_TASK); - discoveryTimer_->Start(DISCOVERY_TIMEOUT, TimeOut, this); + if (timerHeap_ == nullptr) { + timerHeap_ = std::make_shared(); + } + timerHeap_->AddTimer(DISCOVERY_TIMEOUT_TASK, DISCOVERY_TIMEOUT, TimeOut, this); return softbusConnector_->StartDiscovery(subscribeInfo); } @@ -85,7 +86,7 @@ int32_t DmDiscoveryManager::StopDeviceDiscovery(const std::string &pkgName, uint if (!discoveryContextMap_.empty()) { discoveryContextMap_.erase(pkgName); softbusConnector_->UnRegisterSoftbusDiscoveryCallback(pkgName); - discoveryTimer_->Stop(SESSION_CANCEL_TIMEOUT); + timerHeap_->DelTimer(DISCOVERY_TIMEOUT_TASK); } return softbusConnector_->StopDiscovery(subscribeId); } -- Gitee