Skip to content

Commit d1b6b7b

Browse files
committed
Avoid listener is not called
1 parent 335a7d1 commit d1b6b7b

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

lib/Future.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class InternalState {
3939
{
4040
INITIAL,
4141
COMPLETING,
42-
COMPLETED
42+
COMPLETED,
43+
LISTENERS_EMPTY
4344
};
4445

4546
// NOTE: Add the constructor explicitly just to be compatible with GCC 4.8
@@ -54,6 +55,15 @@ class InternalState {
5455
listener(result, value);
5556
} else {
5657
tailListener_ = listeners_.emplace_after(tailListener_, std::move(listener));
58+
if (status_ == LISTENERS_EMPTY) {
59+
auto listeners = std::move(listeners_);
60+
auto result = result_;
61+
auto value = value_;
62+
lock.unlock();
63+
for (auto &&listener : listeners) {
64+
listener(result, value);
65+
}
66+
}
5767
}
5868
}
5969

@@ -70,9 +80,12 @@ class InternalState {
7080
value_ = value;
7181
status_ = COMPLETED;
7282
cond_.notify_all();
83+
lock.unlock();
7384

85+
lock.lock();
7486
if (!listeners_.empty()) {
7587
auto listeners = std::move(listeners_);
88+
status_ = LISTENERS_EMPTY;
7689
lock.unlock();
7790
for (auto &&listener : listeners) {
7891
listener(result, value);
@@ -82,7 +95,7 @@ class InternalState {
8295
return true;
8396
}
8497

85-
bool completed() const noexcept { return status_.load() == COMPLETED; }
98+
bool completed() const noexcept { return status_.load() >= COMPLETED; }
8699

87100
Result get(Type &value) const {
88101
Lock lock{mutex_};

0 commit comments

Comments
 (0)