Race condition in resume_foreground(DispatcherQueue)

It's possible for the lambda to run before control
returns to the caller of TryEnqueue. This led to async_suspend
accessing m_queued after it has already been destroyed
by the lambda.

We make the lambda responsible for setting m_queued prior to
resuming the coroutine.  The lambda can infer that the task
was queued by the fact that the lambda is running at all!

If the enqueue fails, then m_queued remains at its initial
value of false.
This commit is contained in:
Raymond Chen 2019-10-10 20:43:34 -07:00
Родитель ae0378373d
Коммит 9c123d1b60
1 изменённых файлов: 2 добавлений и 4 удалений

Просмотреть файл

@ -25,16 +25,14 @@ WINRT_EXPORT namespace winrt
bool await_suspend(std::experimental::coroutine_handle<> handle)
{
m_queued = m_dispatcher.TryEnqueue(m_priority, [handle]
return m_dispatcher.TryEnqueue(m_priority, [handle, this]
{
m_queued = true;
handle();
});
return m_queued;
}
private:
Windows::System::DispatcherQueue const& m_dispatcher;
Windows::System::DispatcherQueuePriority const m_priority;
bool m_queued{};