Commit 8b829f52 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook Github Bot

Fix casting operators in Executor::KeepAlive

Summary:
Pointer value may change when casting.

(Note: this ignores all push blocking failures!)

Reviewed By: lbrandy

Differential Revision: D7884048

fbshipit-source-id: aa55e1b3530bc28f7d2ffd356761d962d6029832
parent 64b6d1b6
...@@ -58,21 +58,30 @@ class Executor { ...@@ -58,21 +58,30 @@ class Executor {
reset(); reset();
} }
KeepAlive(KeepAlive&& other) noexcept
: executorAndDummyFlag_(exchange(other.executorAndDummyFlag_, 0)) {}
template < template <
typename OtherExecutor, typename OtherExecutor,
typename = typename std::enable_if< typename = typename std::enable_if<
std::is_convertible<OtherExecutor*, ExecutorT*>::value>::type> std::is_convertible<OtherExecutor*, ExecutorT*>::value>::type>
/* implicit */ KeepAlive(KeepAlive<OtherExecutor>&& other) noexcept /* implicit */ KeepAlive(KeepAlive<OtherExecutor>&& other) noexcept
: executorAndDummyFlag_(exchange(other.executorAndDummyFlag_, 0)) {} : KeepAlive(other.get(), other.executorAndDummyFlag_ & kDummyFlag) {
other.executorAndDummyFlag_ = 0;
}
KeepAlive& operator=(KeepAlive&& other) {
reset();
executorAndDummyFlag_ = exchange(other.executorAndDummyFlag_, 0);
return *this;
}
template < template <
typename OtherExecutor, typename OtherExecutor,
typename = typename std::enable_if< typename = typename std::enable_if<
std::is_convertible<OtherExecutor*, ExecutorT*>::value>::type> std::is_convertible<OtherExecutor*, ExecutorT*>::value>::type>
KeepAlive& operator=(KeepAlive<OtherExecutor>&& other) { KeepAlive& operator=(KeepAlive<OtherExecutor>&& other) {
reset(); return *this = KeepAlive(std::move(other));
executorAndDummyFlag_ = exchange(other.executorAndDummyFlag_, 0);
return *this;
} }
void reset() { void reset() {
......
...@@ -1935,6 +1935,11 @@ TEST(EventBaseTest, LoopKeepAliveAtomic) { ...@@ -1935,6 +1935,11 @@ TEST(EventBaseTest, LoopKeepAliveAtomic) {
} }
} }
TEST(EventBaseTest, LoopKeepAliveCast) {
EventBase evb;
Executor::KeepAlive<> keepAlive = getKeepAliveToken(evb);
}
TEST(EventBaseTest, DrivableExecutorTest) { TEST(EventBaseTest, DrivableExecutorTest) {
folly::Promise<bool> p; folly::Promise<bool> p;
auto f = p.getFuture(); auto f = p.getFuture();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment