v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
operations-barrier.h
Go to the documentation of this file.
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_TASKS_OPERATIONS_BARRIER_H_
6#define V8_TASKS_OPERATIONS_BARRIER_H_
7
8#include <cstdint>
9
10#include "src/base/macros.h"
13
14namespace v8 {
15namespace internal {
16
17// A thread-safe barrier to manage lifetime of muti-threaded operations.
18//
19// The barrier is used to determine if operations are allowed, and to keep track
20// of how many are currently active. Users will call TryLock() before starting
21// such operations. If the call succeeds the user can run the operation and the
22// barrier will keep track of it until the user signals that the operation is
23// completed. No operations are allowed after CancelAndWait() is called.
24//
25// There is no explicit way of telling the barrier when an operation is
26// completed, instead for convenience TryLock() will return a RAII
27// like object that will do so on destruction.
28//
29// For example:
30//
31// OperationsBarrier barrier_;
32//
33// void TearDown() {
34// barrier_.CancelAndWait();
35// }
36//
37// void MaybeRunOperation() {
38// if (token = barrier_.TryLock()) Process();
39// }
40//
42 public:
43 // The owner of a Token which evaluates to true can safely perform an
44 // operation while being certain it happens-before CancelAndWait(). Releasing
45 // this Token relinquishes this right.
46 //
47 // This class is thread-safe.
48 class Token {
49 public:
50 Token() = default;
52 if (outer_) outer_->Release();
53 }
54 Token(const Token&) = delete;
55 Token(Token&& other) V8_NOEXCEPT : outer_(other.outer_) {
56 other.outer_ = nullptr;
57 }
58
59 Token& operator=(const Token&) = delete;
61 DCHECK_NE(this, &other);
62 if (outer_) outer_->Release();
63 outer_ = other.outer_;
64 other.outer_ = nullptr;
65 return *this;
66 }
67
68 operator bool() const { return !!outer_; }
69
70 private:
71 friend class OperationsBarrier;
72 explicit Token(OperationsBarrier* outer) : outer_(outer) {
73 DCHECK_NOT_NULL(outer_);
74 }
75 OperationsBarrier* outer_ = nullptr;
76 };
77
78 OperationsBarrier() = default;
79
80 // Users must call CancelAndWait() before destroying an instance of this
81 // class.
82 ~OperationsBarrier() { DCHECK(cancelled_); }
83
86
87 // Returns a RAII like object that implicitly converts to true if operations
88 // are allowed i.e. if this call happens-before CancelAndWait(), otherwise the
89 // object will convert to false. On successful return, this OperationsBarrier
90 // will keep track of the operation until the returned object goes out of
91 // scope.
92 Token TryLock();
93
94 // Prevents further calls to TryLock() from succeeding and waits for
95 // all the ongoing operations to complete.
96 //
97 // Attention: Can only be called once.
98 void CancelAndWait();
99
100 bool cancelled() const { return cancelled_; }
101
102 private:
103 void Release();
104
105 // Mutex and condition variable enabling concurrent register and removing, as
106 // well as waiting for background tasks on {CancelAndWait}.
109 bool cancelled_ = false;
110 size_t operations_count_{0};
111};
112
113} // namespace internal
114} // namespace v8
115
116#endif // V8_TASKS_OPERATIONS_BARRIER_H_
Token & operator=(Token &&other) V8_NOEXCEPT
Token & operator=(const Token &)=delete
OperationsBarrier & operator=(const OperationsBarrier &)=delete
base::ConditionVariable release_condition_
OperationsBarrier(const OperationsBarrier &)=delete
#define V8_NOEXCEPT
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460