/** * Copyright 2019 Huawei Technologies 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "minddata/dataset/util/cond_var.h" #include "minddata/dataset/util/services.h" #include "minddata/dataset/util/task_manager.h" namespace mindspore { namespace dataset { CondVar::CondVar() : svc_(nullptr), my_name_(Services::GetUniqueID()) {} Status CondVar::Wait(std::unique_lock *lck, const std::function &pred) { try { if (svc_ != nullptr) { // If this cv registers with a global resource tracking, then wait unconditionally. auto f = [this, &pred]() -> bool { return (pred() || this->Interrupted()); }; cv_.wait(*lck, f); // If we are interrupted, override the return value if this is the master thread. // Master thread is being interrupted mostly because of some thread is reporting error. RETURN_IF_NOT_OK(Task::OverrideInterruptRc(this->GetInterruptStatus())); } else { // Otherwise we wake up once a while to check for interrupt (for this thread). auto f = [&pred]() -> bool { return (pred() || this_thread::is_interrupted()); }; while (!f()) { (void)cv_.wait_for(*lck, std::chrono::milliseconds(1)); } RETURN_IF_INTERRUPTED(); } } catch (const std::exception &e) { RETURN_STATUS_UNEXPECTED(e.what()); } return Status::OK(); } CondVar::~CondVar() noexcept { if (svc_ != nullptr) { (void)svc_->Deregister(my_name_); svc_ = nullptr; } } void CondVar::NotifyOne() noexcept { cv_.notify_one(); } void CondVar::NotifyAll() noexcept { cv_.notify_all(); } Status CondVar::Register(std::shared_ptr svc) { Status rc = svc->Register(my_name_, this); if (rc.IsOk()) { svc_ = svc; } return rc; } void CondVar::Interrupt() { IntrpResource::Interrupt(); cv_.notify_all(); } std::string CondVar::my_name() const { return my_name_; } Status CondVar::Deregister() { if (svc_) { Status rc = svc_->Deregister(my_name_); svc_ = nullptr; return rc; } return Status::OK(); } } // namespace dataset } // namespace mindspore