Skip to content

Commit fba255d

Browse files
authored
Cancellation token improvements (#674)
1 parent f48d7a6 commit fba255d

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

strings/base_coroutine_foundation.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ namespace winrt::impl
273273
return m_promise->Status() == Windows::Foundation::AsyncStatus::Canceled;
274274
}
275275

276-
void callback(winrt::delegate<>&& cancel) noexcept
276+
void callback(winrt::delegate<>&& cancel) const noexcept
277277
{
278278
m_promise->cancellation_callback(std::move(cancel));
279279
}
@@ -559,7 +559,10 @@ namespace winrt::impl
559559
}
560560
}
561561

562-
cancel();
562+
if (cancel)
563+
{
564+
cancel();
565+
}
563566
}
564567

565568
#if defined(_DEBUG) && !defined(WINRT_NO_MAKE_DETECTION)

test/test/async_auto_cancel.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ namespace
3939
co_return 1;
4040
}
4141

42+
IAsyncAction ActionForceAutoCancel(HANDLE event)
43+
{
44+
co_await resume_on_signal(event);
45+
46+
// Null out the callback to indicate that we want to cancel
47+
// any existing cancellation callback and rely on auto-cancel.
48+
auto cancel = co_await get_cancellation_token();
49+
cancel.callback(nullptr);
50+
51+
co_await std::experimental::suspend_never();
52+
REQUIRE(false);
53+
}
54+
4255
template <typename F>
4356
void Check(F make)
4457
{
@@ -70,4 +83,5 @@ TEST_CASE("async_auto_cancel")
7083
Check(ActionWithProgress);
7184
Check(Operation);
7285
Check(OperationWithProgress);
86+
Check(ActionForceAutoCancel);
7387
}

test/test/async_cancel_callback.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ namespace
1111

1212
IAsyncAction Action(HANDLE event, bool& canceled)
1313
{
14-
auto cancel = co_await get_cancellation_token();
15-
16-
cancel.callback([&]
17-
{
18-
REQUIRE(!canceled);
19-
canceled = true;
20-
});
14+
// Put the cancellation token into a lambda just to make
15+
// sure it's possible.
16+
[cancel = co_await get_cancellation_token(), &canceled]
17+
{
18+
cancel.callback([&]
19+
{
20+
REQUIRE(!canceled);
21+
canceled = true;
22+
});
23+
}();
2124

2225
co_await resume_on_signal(event);
2326
co_await std::experimental::suspend_never();

0 commit comments

Comments
 (0)