Commit 5bf0e525 authored by Lewis Baker's avatar Lewis Baker Committed by Facebook Github Bot

Add ability to construct an invalid CancellationSource

Summary:
Adds static factory `CancellationSource::invalid()`.

This can be used to construct a `CancellationSource` that can't be cancelled but that doesn't perform any heap-allocations.

Reviewed By: kirkshoop

Differential Revision: D16816764

fbshipit-source-id: bb87273903a6a8d245d207f4e6bda94e5c3d3dad
parent a745237d
...@@ -193,6 +193,10 @@ inline CancellationSource& CancellationSource::operator=( ...@@ -193,6 +193,10 @@ inline CancellationSource& CancellationSource::operator=(
return *this; return *this;
} }
inline CancellationSource CancellationSource::invalid() noexcept {
return CancellationSource{detail::CancellationStateSourcePtr{}};
}
inline bool CancellationSource::isCancellationRequested() const noexcept { inline bool CancellationSource::isCancellationRequested() const noexcept {
return state_ != nullptr && state_->isCancellationRequested(); return state_ != nullptr && state_->isCancellationRequested();
} }
...@@ -219,6 +223,10 @@ inline void CancellationSource::swap(CancellationSource& other) noexcept { ...@@ -219,6 +223,10 @@ inline void CancellationSource::swap(CancellationSource& other) noexcept {
std::swap(state_, other.state_); std::swap(state_, other.state_);
} }
inline CancellationSource::CancellationSource(
detail::CancellationStateSourcePtr&& state) noexcept
: state_(std::move(state)) {}
template < template <
typename Callable, typename Callable,
std::enable_if_t< std::enable_if_t<
......
...@@ -139,6 +139,13 @@ class CancellationSource { ...@@ -139,6 +139,13 @@ class CancellationSource {
CancellationSource& operator=(const CancellationSource& other) noexcept; CancellationSource& operator=(const CancellationSource& other) noexcept;
CancellationSource& operator=(CancellationSource&& other) noexcept; CancellationSource& operator=(CancellationSource&& other) noexcept;
// Construct a CancellationSource that cannot be cancelled.
//
// This factory function can be used to obtain a CancellationSource that
// is equivalent to a moved-from CancellationSource object without needing
// to allocate any shared-state.
static CancellationSource invalid() noexcept;
// Query if cancellation has already been requested on this CancellationSource // Query if cancellation has already been requested on this CancellationSource
// or any other CancellationSource object copied from the same original // or any other CancellationSource object copied from the same original
// CancellationSource object. // CancellationSource object.
...@@ -185,6 +192,9 @@ class CancellationSource { ...@@ -185,6 +192,9 @@ class CancellationSource {
const CancellationSource& b) noexcept; const CancellationSource& b) noexcept;
private: private:
explicit CancellationSource(
detail::CancellationStateSourcePtr&& state) noexcept;
detail::CancellationStateSourcePtr state_; detail::CancellationStateSourcePtr state_;
}; };
......
...@@ -245,3 +245,17 @@ TEST(CancellationTokenTest, ManyConcurrentCallbackAddRemove) { ...@@ -245,3 +245,17 @@ TEST(CancellationTokenTest, ManyConcurrentCallbackAddRemove) {
t.join(); t.join();
} }
} }
TEST(CancellationTokenTest, NonCancellableSource) {
CancellationSource src = CancellationSource::invalid();
CHECK(!src.canBeCancelled());
CHECK(!src.isCancellationRequested());
CHECK(!src.requestCancellation());
CHECK(!src.isCancellationRequested());
CHECK(!src.canBeCancelled());
auto token = src.getToken();
CHECK(!src.canBeCancelled());
CHECK(!src.isCancellationRequested());
CHECK(token == CancellationToken{});
}
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