Action Engine
Loading...
Searching...
No Matches
boost_primitives.h
1// Copyright 2025 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef THREAD_BOOST_PRIMITIVES_H_
16#define THREAD_BOOST_PRIMITIVES_H_
17
18#include <absl/base/thread_annotations.h>
19#include <absl/log/log.h>
20#include <absl/status/status.h>
21#include <absl/time/clock.h>
22#include <boost/fiber/condition_variable.hpp>
23#include <boost/fiber/mutex.hpp>
24
25namespace act::concurrency::impl {
26class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED Mutex {
27 public:
28 Mutex() = default;
29 ~Mutex() = default;
30
31 void Lock() noexcept ABSL_EXCLUSIVE_LOCK_FUNCTION();
32 void Unlock() noexcept ABSL_UNLOCK_FUNCTION();
33
34 void lock() noexcept ABSL_EXCLUSIVE_LOCK_FUNCTION() { Lock(); }
35
36 void unlock() noexcept ABSL_UNLOCK_FUNCTION() { Unlock(); }
37
38 friend class CondVar;
39
40 private:
41 boost::fibers::mutex& GetImpl();
42 boost::fibers::mutex mu_;
43};
44
45class ABSL_SCOPED_LOCKABLE MutexLock {
46 public:
47 explicit MutexLock(Mutex* absl_nonnull mu) ABSL_EXCLUSIVE_LOCK_FUNCTION
48
49 (mu)
50 : mu_(mu) {
51 mu_->Lock();
52 }
53
54 MutexLock(const MutexLock&) = delete; // NOLINT(runtime/mutex)
55 MutexLock(MutexLock&&) = delete; // NOLINT(runtime/mutex)
56 MutexLock& operator=(const MutexLock&) = delete;
57 MutexLock& operator=(MutexLock&&) = delete;
58
59 ~MutexLock() ABSL_UNLOCK_FUNCTION() { mu_->Unlock(); }
60
61 private:
62 Mutex* absl_nonnull const mu_;
63};
64
65class CondVar {
66 public:
67 CondVar() = default;
68
69 CondVar(const CondVar&) = delete;
70 CondVar& operator=(const CondVar&) = delete;
71
72 void Wait(Mutex* absl_nonnull mu) noexcept ABSL_SHARED_LOCKS_REQUIRED(mu);
73
74 bool WaitWithTimeout(Mutex* absl_nonnull mu, absl::Duration timeout) noexcept
75
76 ABSL_SHARED_LOCKS_REQUIRED(mu) {
77 return WaitWithDeadline(mu, absl::Now() + timeout);
78 }
79
80 bool WaitWithDeadline(Mutex* absl_nonnull mu,
81 const absl::Time& deadline) noexcept
82 ABSL_SHARED_LOCKS_REQUIRED(mu);
83
84 void Signal() noexcept {
85 try {
86 cv_.notify_one();
87 } catch (boost::fibers::lock_error& error) {
88 LOG(FATAL) << "Error in underlying implementation: " << error.what();
89 ABSL_ASSUME(false);
90 }
91 }
92
93 void SignalAll() noexcept {
94 try {
95 cv_.notify_all();
96 } catch (boost::fibers::lock_error& error) {
97 LOG(FATAL) << "Error in underlying implementation: " << error.what();
98 ABSL_ASSUME(false);
99 }
100 }
101
102 private:
103 boost::fibers::condition_variable_any cv_;
104};
105
106inline void SleepFor(absl::Duration duration) {
107 boost::fibers::context* active_ctx = boost::fibers::context::active();
108 active_ctx->wait_until(std::chrono::steady_clock::now() +
109 absl::ToChronoNanoseconds(duration));
110}
111} // namespace act::concurrency::impl
112
113#endif // THREAD_BOOST_PRIMITIVES_H_