Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions strings/base_coroutine_foundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,18 @@ WINRT_EXPORT namespace winrt::impl
return wait_for_completed(async, static_cast<std::uint32_t>(milliseconds));
}

inline void check_status_canceled(Windows::Foundation::AsyncStatus status)
inline void check_status_canceled(Windows::Foundation::AsyncStatus status, bool originate = true)
{
if (status == Windows::Foundation::AsyncStatus::Canceled)
{
throw hresult_canceled();
if (originate)
{
throw hresult_canceled();
}
else
{
throw hresult_canceled(hresult_error::no_originate);
}
}
}

Expand Down Expand Up @@ -184,7 +191,7 @@ WINRT_EXPORT namespace winrt::impl
auto await_resume() const
{
check_hresult(failure);
check_status_canceled(status);
check_status_canceled(status, this->should_originate_on_cancel());
return async.GetResults();
}

Expand Down Expand Up @@ -487,7 +494,7 @@ WINRT_EXPORT namespace winrt::impl
if (m_status.load(std::memory_order_relaxed) == AsyncStatus::Started)
{
m_status.store(AsyncStatus::Canceled, std::memory_order_relaxed);
if (cancellable_promise::originate_on_cancel())
if (this->should_originate_on_cancel())
{
m_exception = std::make_exception_ptr(hresult_canceled());
}
Expand Down Expand Up @@ -638,7 +645,7 @@ WINRT_EXPORT namespace winrt::impl
{
if (Status() == AsyncStatus::Canceled)
{
if (cancellable_promise::originate_on_cancel())
if (this->should_originate_on_cancel())
{
throw winrt::hresult_canceled();
}
Expand Down
27 changes: 25 additions & 2 deletions strings/base_coroutine_threadpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,18 @@ WINRT_EXPORT namespace winrt
{
if constexpr (std::is_base_of_v<cancellable_promise, T>)
{
// Captured at suspend time so that await_resume need not reach for the
// promise, which may already have completed and released resources.
m_originate_on_cancel = handle.promise().should_originate_on_cancel();
set_cancellable_promise(&handle.promise());
}
}

bool should_originate_on_cancel() const noexcept
{
return m_originate_on_cancel;
}

private:
void set_cancellable_promise(cancellable_promise* promise)
{
Expand All @@ -251,6 +259,7 @@ WINRT_EXPORT namespace winrt
}

cancellable_promise* m_promise = nullptr;
bool m_originate_on_cancel = true;
};

[[nodiscard]] inline auto resume_background() noexcept
Expand Down Expand Up @@ -405,7 +414,14 @@ WINRT_EXPORT namespace winrt::impl
{
if (m_state.exchange(state::idle, std::memory_order_relaxed) == state::canceled)
{
throw hresult_canceled();
if (should_originate_on_cancel())
{
throw hresult_canceled();
}
else
{
throw hresult_canceled(hresult_error::no_originate);
}
}
}

Expand Down Expand Up @@ -513,7 +529,14 @@ WINRT_EXPORT namespace winrt::impl
{
if (m_state.exchange(state::idle, std::memory_order_relaxed) == state::canceled)
{
throw hresult_canceled();
if (should_originate_on_cancel())
{
throw hresult_canceled();
}
else
{
throw hresult_canceled(hresult_error::no_originate);
}
}
return m_result == 0;
}
Expand Down
Loading