Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
fml
synchronization
waitable_event.cc
Go to the documentation of this file.
1
// Copyright 2013 The Flutter 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
#include "flutter/fml/synchronization/waitable_event.h"
6
7
#include <cerrno>
8
#include <ctime>
9
10
#include "flutter/fml/logging.h"
11
#include "flutter/fml/time/time_delta.h"
12
#include "flutter/fml/time/time_point.h"
13
14
namespace
fml
{
15
16
// Waits with a timeout on |condition()|. Returns true on timeout, or false if
17
// |condition()| ever returns true. |condition()| should have no side effects
18
// (and will always be called with |*mutex| held).
19
template
<
typename
ConditionFn>
20
bool
WaitWithTimeoutImpl
(std::unique_lock<std::mutex>* locker,
21
std::condition_variable* cv,
22
ConditionFn condition,
23
TimeDelta
timeout) {
24
FML_DCHECK
(locker->owns_lock());
25
26
if
(condition()) {
27
return
false
;
28
}
29
30
// We may get spurious wakeups.
31
TimeDelta
wait_remaining = timeout;
32
TimePoint
start
=
TimePoint::Now
();
33
while
(
true
) {
34
if
(std::cv_status::timeout ==
35
cv->wait_for(*locker, std::chrono::nanoseconds(
36
wait_remaining.
ToNanoseconds
()))) {
37
return
true
;
// Definitely timed out.
38
}
39
40
// We may have been awoken.
41
if
(condition()) {
42
return
false
;
43
}
44
45
// Or the wakeup may have been spurious.
46
TimePoint
now =
TimePoint::Now
();
47
FML_DCHECK
(now >=
start
);
48
TimeDelta
elapsed = now -
start
;
49
// It's possible that we may have timed out anyway.
50
if
(elapsed >= timeout) {
51
return
true
;
52
}
53
54
// Otherwise, recalculate the amount that we have left to wait.
55
wait_remaining = timeout - elapsed;
56
}
57
}
58
59
// AutoResetWaitableEvent ------------------------------------------------------
60
61
void
AutoResetWaitableEvent::Signal
() {
62
std::scoped_lock locker(mutex_);
63
signaled_ =
true
;
64
cv_.notify_one();
65
}
66
67
void
AutoResetWaitableEvent::Reset
() {
68
std::scoped_lock locker(mutex_);
69
signaled_ =
false
;
70
}
71
72
void
AutoResetWaitableEvent::Wait
() {
73
std::unique_lock<std::mutex> locker(mutex_);
74
while
(!signaled_) {
75
cv_.wait(locker);
76
}
77
signaled_ =
false
;
78
}
79
80
bool
AutoResetWaitableEvent::WaitWithTimeout
(
TimeDelta
timeout) {
81
std::unique_lock<std::mutex> locker(mutex_);
82
83
if
(signaled_) {
84
signaled_ =
false
;
85
return
false
;
86
}
87
88
// We may get spurious wakeups.
89
TimeDelta
wait_remaining = timeout;
90
TimePoint
start
=
TimePoint::Now
();
91
while
(
true
) {
92
if
(std::cv_status::timeout ==
93
cv_.wait_for(
94
locker, std::chrono::nanoseconds(wait_remaining.
ToNanoseconds
()))) {
95
return
true
;
// Definitely timed out.
96
}
97
98
// We may have been awoken.
99
if
(signaled_) {
100
break
;
101
}
102
103
// Or the wakeup may have been spurious.
104
TimePoint
now =
TimePoint::Now
();
105
FML_DCHECK
(now >=
start
);
106
TimeDelta
elapsed = now -
start
;
107
// It's possible that we may have timed out anyway.
108
if
(elapsed >= timeout) {
109
return
true
;
110
}
111
112
// Otherwise, recalculate the amount that we have left to wait.
113
wait_remaining = timeout - elapsed;
114
}
115
116
signaled_ =
false
;
117
return
false
;
118
}
119
120
bool
AutoResetWaitableEvent::IsSignaledForTest
() {
121
std::scoped_lock locker(mutex_);
122
return
signaled_;
123
}
124
125
// ManualResetWaitableEvent ----------------------------------------------------
126
127
void
ManualResetWaitableEvent::Signal
() {
128
std::scoped_lock locker(mutex_);
129
signaled_ =
true
;
130
signal_id_++;
131
cv_.notify_all();
132
}
133
134
void
ManualResetWaitableEvent::Reset
() {
135
std::scoped_lock locker(mutex_);
136
signaled_ =
false
;
137
}
138
139
void
ManualResetWaitableEvent::Wait
() {
140
std::unique_lock<std::mutex> locker(mutex_);
141
142
if
(signaled_) {
143
return
;
144
}
145
146
auto
last_signal_id = signal_id_;
147
do
{
148
cv_.wait(locker);
149
}
while
(signal_id_ == last_signal_id);
150
}
151
152
bool
ManualResetWaitableEvent::WaitWithTimeout
(
TimeDelta
timeout) {
153
std::unique_lock<std::mutex> locker(mutex_);
154
155
auto
last_signal_id = signal_id_;
156
// Disable thread-safety analysis for the lambda: We could annotate it with
157
// |FML_EXCLUSIVE_LOCKS_REQUIRED(mutex_)|, but then the analyzer currently
158
// isn't able to figure out that |WaitWithTimeoutImpl()| calls it while
159
// holding |mutex_|.
160
bool
rv =
WaitWithTimeoutImpl
(
161
&locker, &cv_,
162
[
this
, last_signal_id]() {
163
// Also check |signaled_| in case we're already signaled.
164
return
signaled_ || signal_id_ != last_signal_id;
165
},
166
timeout);
167
FML_DCHECK
(rv || signaled_ || signal_id_ != last_signal_id);
168
return
rv;
169
}
170
171
bool
ManualResetWaitableEvent::IsSignaledForTest
() {
172
std::scoped_lock locker(mutex_);
173
return
signaled_;
174
}
175
176
}
// namespace fml
fml::AutoResetWaitableEvent::Wait
void Wait()
Definition
waitable_event.cc:72
fml::AutoResetWaitableEvent::Reset
void Reset()
Definition
waitable_event.cc:67
fml::AutoResetWaitableEvent::IsSignaledForTest
bool IsSignaledForTest()
Definition
waitable_event.cc:120
fml::AutoResetWaitableEvent::Signal
void Signal()
Definition
waitable_event.cc:61
fml::AutoResetWaitableEvent::WaitWithTimeout
bool WaitWithTimeout(TimeDelta timeout)
Definition
waitable_event.cc:80
fml::ManualResetWaitableEvent::Signal
void Signal()
Definition
waitable_event.cc:127
fml::ManualResetWaitableEvent::Reset
void Reset()
Definition
waitable_event.cc:134
fml::ManualResetWaitableEvent::IsSignaledForTest
bool IsSignaledForTest()
Definition
waitable_event.cc:171
fml::ManualResetWaitableEvent::Wait
void Wait()
Definition
waitable_event.cc:139
fml::ManualResetWaitableEvent::WaitWithTimeout
bool WaitWithTimeout(TimeDelta timeout)
Definition
waitable_event.cc:152
fml::TimeDelta
Definition
time_delta.h:29
fml::TimeDelta::ToNanoseconds
constexpr int64_t ToNanoseconds() const
Definition
time_delta.h:61
fml::TimePoint
Definition
time_point.h:22
fml::TimePoint::Now
static TimePoint Now()
Definition
time_point.cc:49
start
glong start
Definition
fl_accessible_text_field.cc:39
FML_DCHECK
#define FML_DCHECK(condition)
Definition
logging.h:103
fml
Definition
ascii_trie.cc:9
fml::WaitWithTimeoutImpl
bool WaitWithTimeoutImpl(std::unique_lock< std::mutex > *locker, std::condition_variable *cv, ConditionFn condition, TimeDelta timeout)
Definition
waitable_event.cc:20
Generated on Fri Apr 26 2024 06:14:06 for Flutter Engine by
1.9.8