Branch data Line data Source code
1 : : /* 2 : : * Copyright (C) 2026 by Thun Lu. All rights reserved. 3 : : * Author: Thun Lu <thun.lu@zohomail.cn> 4 : : * Repo: https://github.com/thun-res/vlink 5 : : * _ __ __ _ __ 6 : : * | | / / / / (_) ____ / /__ 7 : : * | | / / / / / / / __ \ / //_/ 8 : : * | |/ / / /___ / / / / / / / ,< 9 : : * |___/ /_____/ /_/ /_/ /_/ /_/|_| 10 : : * 11 : : * Licensed under the Apache License, Version 2.0 (the "License"); 12 : : * you may not use this file except in compliance with the License. 13 : : * You may obtain a copy of the License at 14 : : * 15 : : * http://www.apache.org/licenses/LICENSE-2.0 16 : : * 17 : : * Unless required by applicable law or agreed to in writing, software 18 : : * distributed under the License is distributed on an "AS IS" BASIS, 19 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 : : * See the License for the specific language governing permissions and 21 : : * limitations under the License. 22 : : */ 23 : : 24 : : #include "./base/condition_variable.h" 25 : : 26 : : #ifdef VLINK_ENABLE_BASE_CONDITION 27 : : 28 : : #include <pthread.h> 29 : : 30 : : #include <cerrno> 31 : : #include <chrono> 32 : : #include <ctime> 33 : : #include <memory> 34 : : #include <mutex> 35 : : 36 : : namespace vlink { 37 : : 38 : : // ConditionVariable 39 : 2257 : ConditionVariable::ConditionVariable() noexcept { 40 : : pthread_condattr_t attr; 41 : : 42 : 2257 : pthread_condattr_init(&attr); 43 : 2257 : pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 44 : 2257 : pthread_cond_init(&cond_, &attr); 45 : 2257 : pthread_condattr_destroy(&attr); 46 : 2257 : } 47 : : 48 : 2256 : ConditionVariable::~ConditionVariable() noexcept { pthread_cond_destroy(&cond_); } 49 : : 50 : 1210 : void ConditionVariable::notify_one() noexcept { pthread_cond_signal(&cond_); } 51 : : 52 : 8888 : void ConditionVariable::notify_all() noexcept { pthread_cond_broadcast(&cond_); } 53 : : 54 : 1380 : void ConditionVariable::wait(std::unique_lock<std::mutex>& lock) noexcept { 55 : 1380 : pthread_cond_wait(&cond_, lock.mutex()->native_handle()); 56 : 1379 : } 57 : : 58 : 2 : ConditionVariable::native_handle_type ConditionVariable::native_handle() noexcept { return &cond_; } 59 : : 60 : 1900 : std::cv_status ConditionVariable::wait_until_steady(std::unique_lock<std::mutex>& lock, 61 : : const std::chrono::steady_clock::time_point& atime) noexcept { 62 [ + + ]: 1900 : if VUNLIKELY (std::chrono::steady_clock::now() >= atime) { 63 : 2 : return std::cv_status::timeout; 64 : : } 65 : : 66 : 1898 : auto s = std::chrono::time_point_cast<std::chrono::seconds>(atime); 67 : 1898 : auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(atime - s); 68 : : 69 : 1898 : struct timespec ts = {static_cast<std::time_t>(s.time_since_epoch().count()), 70 : 1898 : static_cast<long>(ns.count())}; // NOLINT(runtime/int, google-runtime-int) 71 : : 72 : 1898 : int ret = pthread_cond_timedwait(&cond_, lock.mutex()->native_handle(), &ts); 73 : : 74 [ + + ]: 1898 : return (ret == ETIMEDOUT) ? std::cv_status::timeout : std::cv_status::no_timeout; 75 : : } 76 : : 77 : : // ConditionVariableAny 78 : 10 : ConditionVariableAny::ConditionVariableAny() noexcept : shared_state_(std::make_shared<SharedState>()) {} 79 : : 80 : 10 : ConditionVariableAny::~ConditionVariableAny() noexcept = default; 81 : : 82 : 3 : void ConditionVariableAny::notify_one() noexcept { 83 : 3 : std::shared_ptr<SharedState> state = shared_state_; 84 : 3 : std::lock_guard lock(state->mtx); 85 : 3 : state->cv.notify_one(); 86 : 3 : } 87 : : 88 : 1 : void ConditionVariableAny::notify_all() noexcept { 89 : 1 : std::shared_ptr<SharedState> state = shared_state_; 90 : 1 : std::lock_guard lock(state->mtx); 91 : 1 : state->cv.notify_all(); 92 : 1 : } 93 : : 94 : : } // namespace vlink 95 : : 96 : : #endif