SlideShare a Scribd company logo
COROUTINES EVERYWHERE
Alexey Kutumov
Senior software engineer at Kaspersky Lab
AGENDA
Ч resumable_function
Ч co_await
я C++
Fine tuning coroutine
Ч Е RESUMABLE_FUNCTION
RESUMABLE FUNCTION
auto ResumableFunction(std::string someArg) {
DoThis();
co_await StartSomeAsyncOp();
DoThat(someArg);
}
WINAPI SAMPLE (OLD SCHOOL)
struct AsyncContext : public OVERLAPPED {
HANDLE m_event;
AsyncContext()
: OVERLAPPED()
, m_event(::CreateEvent(nullptr, true, true, nullptr)) {
}
static void WINAPI OnWrite(DWORD error, DWORD bytesWritten, LPOVERLAPPED overlapped) {
AsyncContext* me = static_cast<AsyncContext*>(overlapped);
std::cout << "done, bytes written: " << bytesWritten << std::endl;
::SetEvent(me->m_event);
}
};
WINAPI SAMPLE (OLD SCHOOL)
void OldSchoolWinapiWaiter() {
const char data [] = "hello from good ol` C!";
auto file = ::CreateFile("1.txt", ..., FILE_FLAG_OVERLAPPED);
AsyncContext ctx;
std::cout << "starting..." << std::endl;
::WriteFileEx(file, data, sizeof(data) - 1, &ctx, AsyncContext::OnWrite);
::WaitForSingleObjectEx(ctx.m_event, INFINITE, true);
}
WINAPI SAMPLE (C++)
struct AsyncIoBase : private OVERLAPPED {
AsyncIoBase() : OVERLAPPED() {
}
OVERLAPPED* GetOverlapped() {
return static_cast<OVERLAPPED*>(this);
}
template <typename AsyncIoType>
static AsyncIoType* GetAsyncIo(OVERLAPPED* overlapped) {
return static_cast<AsyncIoType*>(overlapped);
}
};
WINAPI SAMPLE (C++)
struct AsyncWriterBase : public AsyncIoBase {
explicit AsyncWriterBase(HANDLE handle)
: AsyncIoBase(), m_handle(handle) {
}
void StartAsyncWrite(const void* data, size_t size) {
::WriteFileEx(m_handle, data, size, GetOverlapped(), OnWrite);
}
virtual void WriteFinished(DWORD bytesWritten) = 0;
static void WINAPI OnWrite(DWORD error, DWORD bytesWritten, LPOVERLAPPED overlapped) {
AsyncWriterBase* me = GetAsyncIo<AsyncWriterBase>(overlapped);
me->WriteFinished(bytesWritten);
}
HANDLE m_handle;
};
WINAPI SAMPLE (C++)
struct WinapiAsyncWriter : public AsyncWriterBase {
explicit WinapiAsyncWriter(HANDLE handle);
HANDLE WriteAsync(const std::string& message) {
m_message = message;
std::cout << "starting ..." << std::endl;
StartAsyncWrite(m_message.data(), m_message.size());
return m_promise;
}
virtual void WriteFinished(DWORD bytesWritten) {
std::cout << "done, bytes written: " << bytesWritten << std::endl;
::SetEvent(m_promise);
}
HANDLE m_promise;
std::string m_message;
WINAPI SAMPLE (C++)
void TryWinApiWaiter() {
auto fileHandle = ::CreateFile("2.txt", ..., FILE_FLAG_OVERLAPPED);
WinapiAsyncWriter asyncWriter{fileHandle};
auto future = asyncWriter.WriteAsync("hello world");
::WaitForSingleObjectEx(future, INFINITE, true);
}
WINAPI SAMPLE (CORO)
struct WinApiAwaitable : AsyncWriterBase {
WinApiAwaitable(HANDLE handle, const char* data, size_t size);
bool await_ready();
void await_suspend(std::coroutine_handle<coro::promise<void>> coroutineHandle);
DWORD await_resume();
private:
std::coroutine_handle<coro::promise<void>> m_coroutineHandle;
const void* m_data;
size_t m_size;
DWORD m_bytesWritten;
virtual void WriteFinished(DWORD bytesWritten);
};
WINAPI SAMPLE (CORO)
coro::future<void> WriteAsync(HANDLE handle, std::string message) {
std::cout << "starting ..." << std::endl;
DWORD bytesWritten = co_await WinApiAwaitable{handle, message.data(), message.size()};
std::cout << "done, bytes written: " << bytesWritten << std::endl;
}
void TrySimpleCoroWaiter() {
auto file = ::CreateFile(TEXT("3.txt"), ..., FILE_FLAG_OVERLAPPED);
auto future = WriteAsync(file, "hello coroutines!");
future.get_value();
}
WINAPI SAMPLE (CORO)
void WinApiAwaitable::await_suspend(std::coroutine_handle<promise_type> handle) {
m_coroutineHandle = handle;
StartAsyncWrite(m_data, m_size);
}
void WinApiAwaitable::WriteFinished(DWORD bytesWritten) {
m_bytesWritten = bytesWritten;
m_coroutineHandle.resume();
}
DWORD WinApiAwaitable::await_resume() {
return m_bytesWritten;
}
Е CO_AWAIT
CO_AWAIT
coro::future<void> WriteAsync(HANDLE handle, std::string message) {
std::cout << "starting ..." << std::endl;
auto bytesWritten = co_await WinApiAwaitable{handle, message.data(), message.size()};
std::cout << "done, bytes written: " << bytesWritten << std::endl;
}
CO_AWAIT
typedef void( *CoroResumeFunction)(void *);
enum class CoroState {Init, Resume};
template <typename PromiseType>
struct coro_frame_header
{
CoroResumeFunction resumeAddr;
PromiseType promise;
CoroState state
explicit coro_frame_header(CoroResumeFunction fn)
: resumeAddr(fn)
, promise()
, state(CoroState::Init){
}
CO_AWAIT
struct FunctionContext : coro_frame_header<coro::promise<void>> {
HANDLE handle;
std::string message;
WinApiAwaitable awaitable;
FunctionContext(HANDLE h, std::string m, CoroResumeFunction fn)
: frame_header(fn)
, handle(h)
, message(std::move(m))
, awaitable(handle, message.data(), message.size()) {
}
};
CO_AWAIT
template <typename PromiseType>
struct coroutine_handle {
coro_frame_header<PromiseType>* m_frame
coroutine_handle(coro_frame_header<PromiseType>* frame)
: m_frame(frame) {
}
void resume() {
m_frame->resumeAddr(m_frame);
}
void destroy();
};
CO_AWAIT
void WinApiAwaitable::await_suspend(std::coroutine_handle<promise_type> handle) {
m_coroutineHandle = handle;
StartAsyncWrite(m_data, m_size);
}
DWORD WinApiAwaitable::await_resume() {
return m_bytesWritten;
}
void WinApiAwaitable::WriteFinished(DWORD bytesWritten) {
m_bytesWritten = bytesWritten;
m_coroutineHandle.resume();
}
CO_AWAIT
coro::future<void> WriteAsync(HANDLE handle, std::string message) {
std::cout << "starting ..." << std::endl;
auto bytesWritten = co_await WinApiAwaitable{handle, message.data(), message.size()};
std::cout << "done, bytes written: " << bytesWritten << std::endl;
}
CO_AWAIT
void CoroFunction(void* rawCtx) {
FunctionContext* ctx = static_cast<FunctionContext*>(rawCtx);
if (ctx->state == CoroState::Init) {
ctx->state = CoroState::Resume;
std::cout << "starting ..." << std::endl;
ctx->awaitable.await_suspend(ctx);
} else {
DWORD bytesWritten = ctx->awaitable.await_resume();
std::cout << "done, bytes written: " << bytesWritten << std::endl;
delete ctx;
}
}
CO_AWAIT
coro::future<void> WriteAsync(HANDLE handle, std::string message) {
FunctionContext* ctx = new FunctionContext{handle, std::move(message), CoroFunction};
CoroFunction(ctx);
return ctx->promise.get_future();
}
Е C++
C++ RUNTIME
void* operator new(size_t size);
void operator delete(void* location, size_t);
ИЛИ
void* operator new(size_t size, std::nothrow_t const &);
void operator delete(void* location, size_t);
C++ RUNTIME
coro::future<void> WriteAsync(HANDLE handle, std::string message) {
FunctionContext* ctx = new FunctionContext{handle, std::move(message), CoroFunction};
CoroFunction(ctx);
return ctx->promise.get_future();
}
C++ RUNTIME
coro::future<void> WriteAsync(HANDLE handle, std::string message) {
typedef std::coroutine_traits<coro::future<void>, HANDLE, std::string> coro_traits;
auto* ctx = new (std::nothrow) FunctionContext{handle, std::move(message), CoroFunction};
if (!ctx) {
return coro_traits::get_return_object_on_allocation_failure();
}
CoroFunction(ctx);
return ctx->promise.get_future();
}
C++ RUNTIME
constexpr ULONG CrtPoolTag = 'CRTP';
void* operator new(size_t size, struct std::nothrow_t const &) {
return ::ExAllocatePoolWithTag(PagedPool, size, CrtPoolTag);
}
void operator delete(void* location, size_t) {
if (location) {
::ExFreePoolWithTag(location, CrtPoolTag);
}
}
FINE TUNING COROUTINE
THEORY (WINDOWS KERNEL + EFI)
(IRQ – km, Task – efi).
(Level) я (IRQL – km, TPL – efi).
я
я.
LEVELS OF EXECUTION
Windows kernel
PASSIVE_LEVEL
APC_LEVEL
DISPATCH_LEVEL
…
DIRQL
…
HIGH_LEVEL
EFI
TPL_APPLICATION
TPL_CALLBACK
TPL_NOTIFY
FW interrupts
TPL_HIGH_LEVEL
INITIAL + FINAL SUSPEND POINTS
coro::future<void> WriteAsync(HANDLE handle, std::string message) {
auto __is = ???.initial_suspend();
__co_await __is;
std::cout << "starting ..." << std::endl;
auto bytesWritten = co_await WinApiAwaitable{handle, message.data(), message.size()};
std::cout << "done, bytes written: " << bytesWritten << std::endl;
auto __fs = ???.final_suspend();
__co_await __fs;
}
INITIAL SUSPEND
coro::future<void> WriteAsync(HANDLE handle, std::string message) {
auto* ctx = new (std::nothrow) FunctionContext{handle, std::move(message), CoroFunction};
if (!ctx) {return ...}
auto is = ctx->promise.initial_suspend();
if (is.await_ready()) {
is.await_resume();
CoroFunction(ctx);
} else {
is.await_suspend(ctx);
}
return ctx->promise.get_future();
}
CONSTRUCTORS IN NOEXCEPT ENVIRONMENT
auto* ctx = new (std::nothrow) FunctionContext{args};
::operator new(sizeof(FunctionContext), std::nothrow);
FunctionContext::FunctionContext(args);
coro::promise<void>::coro::promise<void>();
coro::promise<void>::construct_shared_state();
make_shared_nothrow<State>();
::CreateEvent(nullptr, true, true, nullptr)
INITIAL SUSPEND
struct check_for_broken_promise {
explicit check_for_broken_promise(bool valid) : m_valid(valid) {}
bool await_ready() noexcept { return m_valid; }
void await_suspend(std::experimental::coroutine_handle<promise> coroutine) noexcept {
coroutine.destroy();
}
void await_resume() noexcept {}
const bool m_valid;
};
template <typename Type>
check_for_broken_promise promise<Type>::initial_suspend() {
return check_for_broken_promise{detail::IsValid(m_state)};
}
FINAL SUSPEND
void CoroFunction(FunctionContext* ctx) {
if (ctx->state == CoroState::Init) {
/// starting...
} else {
DWORD bytesWritten = ctx->awaitable.await_resume();
std::cout << "done, bytes written: " << bytesWritten << std::endl;
auto fs = ctx->promise.final_suspend();
if (fs.await_ready()) {
fs.await_resume();
delete ctx; // destroy coro
} else {
fs.await_suspend(ctx);
}
}
SHARED_STATE_BASE
struct shared_state_base {
~shared_state_base() {
DestroyCoroutine();
}
void DestroyCoroutine() {
if (m_coroutine) {m_coroutine.destroy(); m_coroutine = nullptr;}
}
coro::error_code Notify(std::experimental::coroutine_handle<> coroutine = nullptr) {
m_coroutine = coroutine;
return m_event.Notify();
}
PlatformEventType m_event;
std::experimental::coroutine_handle<> m_coroutine;
};
SHARED_STATE_BASE
~future() {
if (m_state) {
m_state->DestroyCoroutine();
}
}
~promise() {
if (m_state) {
m_state->DestroyCoroutine();
}
}
FINAL_SUSPEND
struct notify_and_destroy_coroutine_in_caller_context {
bool await_ready() noexcept {
return false;
}
void await_suspend(std::experimental::coroutine_handle<promise> coroutine) noexcept {
coroutine.promise().notify(coroutine);
}
void await_resume() noexcept { }
};
FINAL_SUSPEND
struct notify_and_destroy_coroutine_in_async_context {
notify_and_destroy_coroutine_in_async_context(coro::shared_state_ptr state)
: m_state(state) { }
bool await_ready() noexcept { return true; }
void await_suspend(std::experimental::coroutine_handle<> /* coroutine */) noexcept { }
void await_resume() noexcept {
m_state->Notify();
}
coro::shared_state_ptr m_state;
};
LET'S TALK?
alexey.kutumov@gmail.com
https://github.com/prograholic/coroutines_km/

More Related Content

PDF
Qt Rest Server
PPT
Евгений Крутько, Многопоточные вычисления, современный подход.
PDF
Антон Бикинеев, Writing good std::future&lt; C++ >
PDF
One definition rule - что это такое, и как с этим жить
PDF
Welcome to Modern C++
PPTX
Lexical environment in ecma 262 5
PPTX
Pro typescript.ch03.Object Orientation in TypeScript
PPTX
Дмитрий Демчук. Кроссплатформенный краш-репорт
Qt Rest Server
Евгений Крутько, Многопоточные вычисления, современный подход.
Антон Бикинеев, Writing good std::future&lt; C++ >
One definition rule - что это такое, и как с этим жить
Welcome to Modern C++
Lexical environment in ecma 262 5
Pro typescript.ch03.Object Orientation in TypeScript
Дмитрий Демчук. Кроссплатформенный краш-репорт

What's hot (20)

PDF
TVM VTA (TSIM)
PDF
Коварный code type ITGM #9
PPT
Whats new in_csharp4
PDF
TensorFlow XLA RPC
PPTX
Basic C++ 11/14 for Python Programmers
PDF
ITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
PPTX
C++ Lambda and concurrency
PPT
为什么 rust-lang 吸引我?
PDF
4. Обработка ошибок, исключения, отладка
PDF
Writing good std::future&lt;c++>
PDF
Flashback, el primer malware masivo de sistemas Mac
PDF
Bridge TensorFlow to run on Intel nGraph backends (v0.4)
PDF
Bridge TensorFlow to run on Intel nGraph backends (v0.5)
PPT
Lecture16
PDF
Chainer-Compiler 動かしてみた
PPTX
PyconKR 2018 Deep dive into Coroutine
PDF
Protocol handler in Gecko
ODP
Отладка в GDB
PPTX
C++ idioms.pptx
TVM VTA (TSIM)
Коварный code type ITGM #9
Whats new in_csharp4
TensorFlow XLA RPC
Basic C++ 11/14 for Python Programmers
ITGM #9 - Коварный CodeType, или от segfault'а к работающему коду
C++ Lambda and concurrency
为什么 rust-lang 吸引我?
4. Обработка ошибок, исключения, отладка
Writing good std::future&lt;c++>
Flashback, el primer malware masivo de sistemas Mac
Bridge TensorFlow to run on Intel nGraph backends (v0.4)
Bridge TensorFlow to run on Intel nGraph backends (v0.5)
Lecture16
Chainer-Compiler 動かしてみた
PyconKR 2018 Deep dive into Coroutine
Protocol handler in Gecko
Отладка в GDB
C++ idioms.pptx
Ad

Viewers also liked (20)

PPTX
Алексей Кутумов, C++ без исключений, часть 3
PPTX
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
PDF
Parallel STL
PDF
Догнать и перегнать boost::lexical_cast
PDF
Использование юнит-тестов для повышения качества разработки
PPTX
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
PPTX
Quality assurance of large c++ projects
PDF
Антон Бикинеев, Reflection in C++Next
PDF
Для чего мы делали свой акторный фреймворк и что из этого вышло?
PPTX
C++ Core Guidelines
PPTX
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
PDF
Василий Сорокин, Простой REST сервер на Qt с рефлексией
PDF
Обзор алгоритмов трекинга объектов
PDF
Plane rectification through robust vanishing point tracking using the expecta...
PDF
Implementation of a lane-tracking system for autonomous driving using Kalman ...
PPTX
Gor Nishanov, C++ Coroutines – a negative overhead abstraction
PPTX
Григорий Демченко, Универсальный адаптер
PDF
Clang tidy
PPTX
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
PDF
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Алексей Кутумов, C++ без исключений, часть 3
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Parallel STL
Догнать и перегнать boost::lexical_cast
Использование юнит-тестов для повышения качества разработки
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Quality assurance of large c++ projects
Антон Бикинеев, Reflection in C++Next
Для чего мы делали свой акторный фреймворк и что из этого вышло?
C++ Core Guidelines
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Обзор алгоритмов трекинга объектов
Plane rectification through robust vanishing point tracking using the expecta...
Implementation of a lane-tracking system for autonomous driving using Kalman ...
Gor Nishanov, C++ Coroutines – a negative overhead abstraction
Григорий Демченко, Универсальный адаптер
Clang tidy
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Ad

Similar to Алексей Кутумов, Coroutines everywhere (19)

PDF
Introduction to C++20 Coroutines by Alex P
PPTX
Async await in C++
PPTX
C++11 Multithreading - Futures
PDF
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
PPTX
Adventures in Thread-per-Core Async with Redpanda and Seastar
PDF
OpenFabrics Interfaces introduction
PPT
Windows Server 2008 for Developers - Part 2
PDF
Refactoring for testability c++
PDF
GPU Programming on CPU - Using C++AMP
PPTX
Effective C++/WinRT for UWP and Win32
PDF
Giorgio zoppi cpp11concurrency
PDF
Programação assíncrona utilizando Coroutines
PDF
Agathos-PHD-uoi-2016
PDF
Agathos-PHD-uoi-2016
PDF
OFI libfabric Tutorial
PPTX
Features of the Modern C++ 20
PDF
Concurrency
PPTX
17. thread and deadlock
Introduction to C++20 Coroutines by Alex P
Async await in C++
C++11 Multithreading - Futures
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
Adventures in Thread-per-Core Async with Redpanda and Seastar
OpenFabrics Interfaces introduction
Windows Server 2008 for Developers - Part 2
Refactoring for testability c++
GPU Programming on CPU - Using C++AMP
Effective C++/WinRT for UWP and Win32
Giorgio zoppi cpp11concurrency
Programação assíncrona utilizando Coroutines
Agathos-PHD-uoi-2016
Agathos-PHD-uoi-2016
OFI libfabric Tutorial
Features of the Modern C++ 20
Concurrency
17. thread and deadlock

More from Sergey Platonov (20)

PPTX
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
PDF
Павел Филонов, Разделяй и управляй вместе с Conan.io
PPTX
Григорий Демченко, Асинхронность и неблокирующая синхронизация
ODP
Антон Полухин. C++17
PPTX
Павел Беликов, Как избежать ошибок, используя современный C++
PDF
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
PPTX
Дмитрий Нестерук, Паттерны проектирования в XXI веке
PPTX
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
PDF
Павел Довгалюк, Обратная отладка
PPTX
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
PPTX
Dori Exterman, Considerations for choosing the parallel computing strategy th...
PDF
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
PPTX
Александр Фокин, Рефлексия в C++
PDF
Антон Нонко, Классические строки в C++
PPTX
Михаил Матросов, Повседневный С++: boost и STL
PDF
Борис Сазонов, RAII потоки и CancellationToken в C++
PPTX
Алексей Кутумов, Вектор с нуля
PDF
Kirk Shoop, Reactive programming in C++
PPTX
Илья Шишков, Принципы создания тестируемого кода
PDF
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Павел Филонов, Разделяй и управляй вместе с Conan.io
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Антон Полухин. C++17
Павел Беликов, Как избежать ошибок, используя современный C++
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Павел Довгалюк, Обратная отладка
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Dori Exterman, Considerations for choosing the parallel computing strategy th...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Фокин, Рефлексия в C++
Антон Нонко, Классические строки в C++
Михаил Матросов, Повседневный С++: boost и STL
Борис Сазонов, RAII потоки и CancellationToken в C++
Алексей Кутумов, Вектор с нуля
Kirk Shoop, Reactive programming in C++
Илья Шишков, Принципы создания тестируемого кода
Антон Наумович, Система автоматической крэш-аналитики своими средствами

Recently uploaded (20)

PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Nekopoi APK 2025 free lastest update
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Salesforce Agentforce AI Implementation.pdf
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
history of c programming in notes for students .pptx
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
PDF
medical staffing services at VALiNTRY
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
CCleaner Pro 6.38.11537 Crack Final Latest Version 2025
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Complete Guide to Website Development in Malaysia for SMEs
PDF
Digital Systems & Binary Numbers (comprehensive )
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
CHAPTER 2 - PM Management and IT Context
Nekopoi APK 2025 free lastest update
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Salesforce Agentforce AI Implementation.pdf
Odoo Companies in India – Driving Business Transformation.pdf
history of c programming in notes for students .pptx
wealthsignaloriginal-com-DS-text-... (1).pdf
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Navsoft: AI-Powered Business Solutions & Custom Software Development
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
medical staffing services at VALiNTRY
L1 - Introduction to python Backend.pptx
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
CCleaner Pro 6.38.11537 Crack Final Latest Version 2025
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Complete Guide to Website Development in Malaysia for SMEs
Digital Systems & Binary Numbers (comprehensive )
How to Choose the Right IT Partner for Your Business in Malaysia

Алексей Кутумов, Coroutines everywhere

  • 1. COROUTINES EVERYWHERE Alexey Kutumov Senior software engineer at Kaspersky Lab
  • 4. RESUMABLE FUNCTION auto ResumableFunction(std::string someArg) { DoThis(); co_await StartSomeAsyncOp(); DoThat(someArg); }
  • 5. WINAPI SAMPLE (OLD SCHOOL) struct AsyncContext : public OVERLAPPED { HANDLE m_event; AsyncContext() : OVERLAPPED() , m_event(::CreateEvent(nullptr, true, true, nullptr)) { } static void WINAPI OnWrite(DWORD error, DWORD bytesWritten, LPOVERLAPPED overlapped) { AsyncContext* me = static_cast<AsyncContext*>(overlapped); std::cout << "done, bytes written: " << bytesWritten << std::endl; ::SetEvent(me->m_event); } };
  • 6. WINAPI SAMPLE (OLD SCHOOL) void OldSchoolWinapiWaiter() { const char data [] = "hello from good ol` C!"; auto file = ::CreateFile("1.txt", ..., FILE_FLAG_OVERLAPPED); AsyncContext ctx; std::cout << "starting..." << std::endl; ::WriteFileEx(file, data, sizeof(data) - 1, &ctx, AsyncContext::OnWrite); ::WaitForSingleObjectEx(ctx.m_event, INFINITE, true); }
  • 7. WINAPI SAMPLE (C++) struct AsyncIoBase : private OVERLAPPED { AsyncIoBase() : OVERLAPPED() { } OVERLAPPED* GetOverlapped() { return static_cast<OVERLAPPED*>(this); } template <typename AsyncIoType> static AsyncIoType* GetAsyncIo(OVERLAPPED* overlapped) { return static_cast<AsyncIoType*>(overlapped); } };
  • 8. WINAPI SAMPLE (C++) struct AsyncWriterBase : public AsyncIoBase { explicit AsyncWriterBase(HANDLE handle) : AsyncIoBase(), m_handle(handle) { } void StartAsyncWrite(const void* data, size_t size) { ::WriteFileEx(m_handle, data, size, GetOverlapped(), OnWrite); } virtual void WriteFinished(DWORD bytesWritten) = 0; static void WINAPI OnWrite(DWORD error, DWORD bytesWritten, LPOVERLAPPED overlapped) { AsyncWriterBase* me = GetAsyncIo<AsyncWriterBase>(overlapped); me->WriteFinished(bytesWritten); } HANDLE m_handle; };
  • 9. WINAPI SAMPLE (C++) struct WinapiAsyncWriter : public AsyncWriterBase { explicit WinapiAsyncWriter(HANDLE handle); HANDLE WriteAsync(const std::string& message) { m_message = message; std::cout << "starting ..." << std::endl; StartAsyncWrite(m_message.data(), m_message.size()); return m_promise; } virtual void WriteFinished(DWORD bytesWritten) { std::cout << "done, bytes written: " << bytesWritten << std::endl; ::SetEvent(m_promise); } HANDLE m_promise; std::string m_message;
  • 10. WINAPI SAMPLE (C++) void TryWinApiWaiter() { auto fileHandle = ::CreateFile("2.txt", ..., FILE_FLAG_OVERLAPPED); WinapiAsyncWriter asyncWriter{fileHandle}; auto future = asyncWriter.WriteAsync("hello world"); ::WaitForSingleObjectEx(future, INFINITE, true); }
  • 11. WINAPI SAMPLE (CORO) struct WinApiAwaitable : AsyncWriterBase { WinApiAwaitable(HANDLE handle, const char* data, size_t size); bool await_ready(); void await_suspend(std::coroutine_handle<coro::promise<void>> coroutineHandle); DWORD await_resume(); private: std::coroutine_handle<coro::promise<void>> m_coroutineHandle; const void* m_data; size_t m_size; DWORD m_bytesWritten; virtual void WriteFinished(DWORD bytesWritten); };
  • 12. WINAPI SAMPLE (CORO) coro::future<void> WriteAsync(HANDLE handle, std::string message) { std::cout << "starting ..." << std::endl; DWORD bytesWritten = co_await WinApiAwaitable{handle, message.data(), message.size()}; std::cout << "done, bytes written: " << bytesWritten << std::endl; } void TrySimpleCoroWaiter() { auto file = ::CreateFile(TEXT("3.txt"), ..., FILE_FLAG_OVERLAPPED); auto future = WriteAsync(file, "hello coroutines!"); future.get_value(); }
  • 13. WINAPI SAMPLE (CORO) void WinApiAwaitable::await_suspend(std::coroutine_handle<promise_type> handle) { m_coroutineHandle = handle; StartAsyncWrite(m_data, m_size); } void WinApiAwaitable::WriteFinished(DWORD bytesWritten) { m_bytesWritten = bytesWritten; m_coroutineHandle.resume(); } DWORD WinApiAwaitable::await_resume() { return m_bytesWritten; }
  • 15. CO_AWAIT coro::future<void> WriteAsync(HANDLE handle, std::string message) { std::cout << "starting ..." << std::endl; auto bytesWritten = co_await WinApiAwaitable{handle, message.data(), message.size()}; std::cout << "done, bytes written: " << bytesWritten << std::endl; }
  • 16. CO_AWAIT typedef void( *CoroResumeFunction)(void *); enum class CoroState {Init, Resume}; template <typename PromiseType> struct coro_frame_header { CoroResumeFunction resumeAddr; PromiseType promise; CoroState state explicit coro_frame_header(CoroResumeFunction fn) : resumeAddr(fn) , promise() , state(CoroState::Init){ }
  • 17. CO_AWAIT struct FunctionContext : coro_frame_header<coro::promise<void>> { HANDLE handle; std::string message; WinApiAwaitable awaitable; FunctionContext(HANDLE h, std::string m, CoroResumeFunction fn) : frame_header(fn) , handle(h) , message(std::move(m)) , awaitable(handle, message.data(), message.size()) { } };
  • 18. CO_AWAIT template <typename PromiseType> struct coroutine_handle { coro_frame_header<PromiseType>* m_frame coroutine_handle(coro_frame_header<PromiseType>* frame) : m_frame(frame) { } void resume() { m_frame->resumeAddr(m_frame); } void destroy(); };
  • 19. CO_AWAIT void WinApiAwaitable::await_suspend(std::coroutine_handle<promise_type> handle) { m_coroutineHandle = handle; StartAsyncWrite(m_data, m_size); } DWORD WinApiAwaitable::await_resume() { return m_bytesWritten; } void WinApiAwaitable::WriteFinished(DWORD bytesWritten) { m_bytesWritten = bytesWritten; m_coroutineHandle.resume(); }
  • 20. CO_AWAIT coro::future<void> WriteAsync(HANDLE handle, std::string message) { std::cout << "starting ..." << std::endl; auto bytesWritten = co_await WinApiAwaitable{handle, message.data(), message.size()}; std::cout << "done, bytes written: " << bytesWritten << std::endl; }
  • 21. CO_AWAIT void CoroFunction(void* rawCtx) { FunctionContext* ctx = static_cast<FunctionContext*>(rawCtx); if (ctx->state == CoroState::Init) { ctx->state = CoroState::Resume; std::cout << "starting ..." << std::endl; ctx->awaitable.await_suspend(ctx); } else { DWORD bytesWritten = ctx->awaitable.await_resume(); std::cout << "done, bytes written: " << bytesWritten << std::endl; delete ctx; } }
  • 22. CO_AWAIT coro::future<void> WriteAsync(HANDLE handle, std::string message) { FunctionContext* ctx = new FunctionContext{handle, std::move(message), CoroFunction}; CoroFunction(ctx); return ctx->promise.get_future(); }
  • 24. C++ RUNTIME void* operator new(size_t size); void operator delete(void* location, size_t); ИЛИ void* operator new(size_t size, std::nothrow_t const &); void operator delete(void* location, size_t);
  • 25. C++ RUNTIME coro::future<void> WriteAsync(HANDLE handle, std::string message) { FunctionContext* ctx = new FunctionContext{handle, std::move(message), CoroFunction}; CoroFunction(ctx); return ctx->promise.get_future(); }
  • 26. C++ RUNTIME coro::future<void> WriteAsync(HANDLE handle, std::string message) { typedef std::coroutine_traits<coro::future<void>, HANDLE, std::string> coro_traits; auto* ctx = new (std::nothrow) FunctionContext{handle, std::move(message), CoroFunction}; if (!ctx) { return coro_traits::get_return_object_on_allocation_failure(); } CoroFunction(ctx); return ctx->promise.get_future(); }
  • 27. C++ RUNTIME constexpr ULONG CrtPoolTag = 'CRTP'; void* operator new(size_t size, struct std::nothrow_t const &) { return ::ExAllocatePoolWithTag(PagedPool, size, CrtPoolTag); } void operator delete(void* location, size_t) { if (location) { ::ExFreePoolWithTag(location, CrtPoolTag); } }
  • 29. THEORY (WINDOWS KERNEL + EFI) (IRQ – km, Task – efi). (Level) я (IRQL – km, TPL – efi). я я.
  • 30. LEVELS OF EXECUTION Windows kernel PASSIVE_LEVEL APC_LEVEL DISPATCH_LEVEL … DIRQL … HIGH_LEVEL EFI TPL_APPLICATION TPL_CALLBACK TPL_NOTIFY FW interrupts TPL_HIGH_LEVEL
  • 31. INITIAL + FINAL SUSPEND POINTS coro::future<void> WriteAsync(HANDLE handle, std::string message) { auto __is = ???.initial_suspend(); __co_await __is; std::cout << "starting ..." << std::endl; auto bytesWritten = co_await WinApiAwaitable{handle, message.data(), message.size()}; std::cout << "done, bytes written: " << bytesWritten << std::endl; auto __fs = ???.final_suspend(); __co_await __fs; }
  • 32. INITIAL SUSPEND coro::future<void> WriteAsync(HANDLE handle, std::string message) { auto* ctx = new (std::nothrow) FunctionContext{handle, std::move(message), CoroFunction}; if (!ctx) {return ...} auto is = ctx->promise.initial_suspend(); if (is.await_ready()) { is.await_resume(); CoroFunction(ctx); } else { is.await_suspend(ctx); } return ctx->promise.get_future(); }
  • 33. CONSTRUCTORS IN NOEXCEPT ENVIRONMENT auto* ctx = new (std::nothrow) FunctionContext{args}; ::operator new(sizeof(FunctionContext), std::nothrow); FunctionContext::FunctionContext(args); coro::promise<void>::coro::promise<void>(); coro::promise<void>::construct_shared_state(); make_shared_nothrow<State>(); ::CreateEvent(nullptr, true, true, nullptr)
  • 34. INITIAL SUSPEND struct check_for_broken_promise { explicit check_for_broken_promise(bool valid) : m_valid(valid) {} bool await_ready() noexcept { return m_valid; } void await_suspend(std::experimental::coroutine_handle<promise> coroutine) noexcept { coroutine.destroy(); } void await_resume() noexcept {} const bool m_valid; }; template <typename Type> check_for_broken_promise promise<Type>::initial_suspend() { return check_for_broken_promise{detail::IsValid(m_state)}; }
  • 35. FINAL SUSPEND void CoroFunction(FunctionContext* ctx) { if (ctx->state == CoroState::Init) { /// starting... } else { DWORD bytesWritten = ctx->awaitable.await_resume(); std::cout << "done, bytes written: " << bytesWritten << std::endl; auto fs = ctx->promise.final_suspend(); if (fs.await_ready()) { fs.await_resume(); delete ctx; // destroy coro } else { fs.await_suspend(ctx); } }
  • 36. SHARED_STATE_BASE struct shared_state_base { ~shared_state_base() { DestroyCoroutine(); } void DestroyCoroutine() { if (m_coroutine) {m_coroutine.destroy(); m_coroutine = nullptr;} } coro::error_code Notify(std::experimental::coroutine_handle<> coroutine = nullptr) { m_coroutine = coroutine; return m_event.Notify(); } PlatformEventType m_event; std::experimental::coroutine_handle<> m_coroutine; };
  • 37. SHARED_STATE_BASE ~future() { if (m_state) { m_state->DestroyCoroutine(); } } ~promise() { if (m_state) { m_state->DestroyCoroutine(); } }
  • 38. FINAL_SUSPEND struct notify_and_destroy_coroutine_in_caller_context { bool await_ready() noexcept { return false; } void await_suspend(std::experimental::coroutine_handle<promise> coroutine) noexcept { coroutine.promise().notify(coroutine); } void await_resume() noexcept { } };
  • 39. FINAL_SUSPEND struct notify_and_destroy_coroutine_in_async_context { notify_and_destroy_coroutine_in_async_context(coro::shared_state_ptr state) : m_state(state) { } bool await_ready() noexcept { return true; } void await_suspend(std::experimental::coroutine_handle<> /* coroutine */) noexcept { } void await_resume() noexcept { m_state->Notify(); } coro::shared_state_ptr m_state; };