Skip to content

Commit 48be0c5

Browse files
authored
[k2] add await set primitive (#1418)
1 parent 332afc8 commit 48be0c5

2 files changed

Lines changed: 459 additions & 0 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Compiler for PHP (aka KPHP)
2+
// Copyright (c) 2025 LLC «V Kontakte»
3+
// Distributed under the GPL v3 License, see LICENSE.notice.txt
4+
5+
#pragma once
6+
7+
#include <cstddef>
8+
#include <memory>
9+
#include <type_traits>
10+
11+
#include "runtime-common/core/allocator/script-allocator.h"
12+
#include "runtime-common/core/std/containers.h"
13+
#include "runtime-light/coroutine/async-stack.h"
14+
#include "runtime-light/coroutine/concepts.h"
15+
#include "runtime-light/coroutine/coroutine-state.h"
16+
#include "runtime-light/coroutine/detail/await-set.h"
17+
#include "runtime-light/coroutine/type-traits.h"
18+
19+
namespace kphp::coro {
20+
21+
template<typename return_type>
22+
class await_set {
23+
kphp::stl::list<detail::await_set::await_set_task<return_type>, kphp::memory::script_allocator> m_tasks_storage{};
24+
std::unique_ptr<detail::await_set::await_broker<return_type>> m_await_broker;
25+
kphp::coro::async_stack_root& m_coroutine_stack_root;
26+
27+
template<typename T>
28+
friend class kphp::coro::detail::await_set::await_broker;
29+
30+
void clear() noexcept {
31+
m_await_broker.release();
32+
m_tasks_storage.clear();
33+
}
34+
35+
public:
36+
explicit await_set() noexcept
37+
: m_await_broker(std::make_unique<detail::await_set::await_broker<return_type>>(*this)),
38+
m_coroutine_stack_root(CoroutineInstanceState::get().coroutine_stack_root) {}
39+
40+
await_set(await_set&& other) noexcept
41+
: m_tasks_storage(std::move(other.m_tasks_storage)),
42+
m_await_broker(std::move(other.m_await_broker)),
43+
m_coroutine_stack_root(other.m_coroutine_stack_root) {}
44+
45+
await_set& operator=(await_set&& other) noexcept {
46+
if (this != std::addressof(other)) {
47+
clear();
48+
m_tasks_storage = std::move(other.m_tasks_storage);
49+
m_await_broker = std::move(other.m_await_broker);
50+
m_coroutine_stack_root = other.m_coroutine_stack_root;
51+
}
52+
return *this;
53+
}
54+
55+
await_set(const await_set&) = delete;
56+
await_set& operator=(const await_set&) = delete;
57+
58+
template<typename awaitable_type>
59+
requires kphp::coro::concepts::awaitable<awaitable_type> && std::is_same_v<typename awaitable_traits<awaitable_type>::awaiter_return_type, return_type>
60+
void push(awaitable_type awaitable) noexcept {
61+
auto task_iterator{m_tasks_storage.insert(m_tasks_storage.begin(), detail::await_set::make_await_set_task(std::move(awaitable)))};
62+
task_iterator->start(*m_await_broker.get(), task_iterator, m_coroutine_stack_root, STACK_RETURN_ADDRESS);
63+
}
64+
65+
auto next() noexcept {
66+
return detail::await_set::await_set_awaitable<return_type>{*m_await_broker.get()};
67+
}
68+
69+
bool empty() const noexcept {
70+
return len() == 0;
71+
}
72+
73+
size_t len() const noexcept {
74+
return m_tasks_storage.size();
75+
}
76+
77+
~await_set() {
78+
clear();
79+
}
80+
};
81+
82+
} // namespace kphp::coro

0 commit comments

Comments
 (0)