cutelyst 4.5.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
CoroContext.h
1/*
2 * SPDX-FileCopyrightText: (C) 2020-2023 Daniel Nicoletti <dantti12@gmail.com>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#pragma once
6
7#include <Cutelyst/async.h>
8#include <coroutine>
9#include <functional>
10#include <memory>
11
12#include <QObject>
13
14namespace Cutelyst {
15
31{
32public:
33 struct promise_type {
34 std::coroutine_handle<promise_type> handle;
35 std::vector<QMetaObject::Connection> connections;
36
37 void clean()
38 {
39 for (auto &conn : connections) {
40 QObject::disconnect(conn);
41 }
42 connections.clear();
43 }
44
45 void return_void() noexcept {}
46
47 CoroContext get_return_object()
48 {
49 handle = std::coroutine_handle<promise_type>::from_promise(*this);
50 return {};
51 }
52
53 std::suspend_never initial_suspend() const noexcept { return {}; }
54 std::suspend_never final_suspend() noexcept { return {}; }
55 void unhandled_exception() {}
56
57 bool await_ready() const noexcept { return false; }
58
59 std::suspend_never yield_value(QObject *obj)
60 {
61 // Automatically delay replies
62 // async cannot be used in coroutine body
63 // else we get a double free when the coroutine
64 // body ends and Cutelyst::Engine deletes the Context*
65 // resulting in destroyed signal being emitted and
66 // and coroutine dtor already on the stack to be called
67 ASync a(qobject_cast<Cutelyst::Context *>(obj));
68
69 auto conn = QObject::connect(obj, &QObject::destroyed, [this, a](QObject *obj) {
70 clean();
71
72 if (handle) {
73 handle.destroy();
74 }
75 });
76 connections.emplace_back(std::move(conn));
77 return {};
78 }
79 void await_suspend(std::coroutine_handle<> h) noexcept {}
80 void await_resume() const noexcept {}
81
82 ~promise_type() { clean(); }
83 };
84};
85
86} // namespace Cutelyst
Helper class for asynchronous processing.
Definition async.h:16
The CoroContext class.
Definition CoroContext.h:31
The Cutelyst namespace holds all public Cutelyst API.