libcopp 2.3.1
Loading...
Searching...
No Matches
coroutine_context_fiber.h
Go to the documentation of this file.
1// Copyright 2023 owent
2
3#pragma once
4
5#include <libcopp/utils/config/libcopp_build_features.h>
7
8// clang-format off
9#include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
10// clang-format on
11#include <cstddef>
12// clang-format off
13#include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
14// clang-format on
15
18
19#if defined(LIBCOPP_MACRO_ENABLE_WIN_FIBER) && LIBCOPP_MACRO_ENABLE_WIN_FIBER
20
21# ifndef WIN32_LEAN_AND_MEAN
22# define WIN32_LEAN_AND_MEAN
23# endif
24
25# include <Windows.h> // NOLINT(build/include_order)
26
27LIBCOPP_COPP_NAMESPACE_BEGIN
31class coroutine_context_fiber : public coroutine_context_base {
32 public:
33 using ptr_type = LIBCOPP_COPP_NAMESPACE_ID::memory::intrusive_ptr<coroutine_context_fiber>;
34
35 using callback_type = coroutine_context_base::callback_type;
36 using status_type = coroutine_context_base::status_type;
37 using flag_type = coroutine_context_base::flag_type;
38
39 // Compability with libcopp-1.x
40 using ptr_t = ptr_type;
41 using callback_t = callback_type;
42 using status_t = status_type;
43 using flag_t = flag_type;
44
45 private:
52# if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
53 using coroutine_context_base::unhandle_exception_;
54# endif
55
56 struct jump_src_data_t {
57 coroutine_context_fiber *from_co;
58 LPVOID from_fiber;
59 coroutine_context_fiber *to_co;
60 LPVOID to_fiber;
61 void *priv_data;
62 };
63
64 friend struct LIBCOPP_COPP_API_HEAD_ONLY libcopp_fiber_internal_api_set;
65 friend struct LIBCOPP_COPP_API_HEAD_ONLY fiber_context_tls_data_t;
66
67 protected:
68 LPVOID caller_;
69 LPVOID callee_;
71 stack_context callee_stack_;
73 protected:
74 LIBCOPP_COPP_API coroutine_context_fiber() LIBCOPP_MACRO_NOEXCEPT;
75
76 public:
77 LIBCOPP_COPP_API ~coroutine_context_fiber();
78
79 private:
80 coroutine_context_fiber(const coroutine_context_fiber &) = delete;
81 coroutine_context_fiber &operator=(const coroutine_context_fiber &) = delete;
82 coroutine_context_fiber(const coroutine_context_fiber &&) = delete;
83 coroutine_context_fiber &operator=(const coroutine_context_fiber &&) = delete;
84
85 public:
94 static LIBCOPP_COPP_API int create(coroutine_context_fiber *p, callback_type &&runner,
95 const stack_context &callee_stack, size_t coroutine_size,
96 size_t private_buffer_size,
97 size_t stack_reserve_size_of_fiber = 0) LIBCOPP_MACRO_NOEXCEPT;
98
99 template <typename TRunner>
100 static LIBCOPP_COPP_API_HEAD_ONLY int create(coroutine_context_fiber *p, TRunner *runner,
101 const stack_context &callee_stack, size_t coroutine_size,
102 size_t private_buffer_size,
103 size_t stack_reserve_size_of_fiber = 0) LIBCOPP_MACRO_NOEXCEPT {
104 return create(
105 p, [runner](void *private_data) { return (*runner)(private_data); }, callee_stack, coroutine_size,
106 private_buffer_size, stack_reserve_size_of_fiber);
107 }
108
115 LIBCOPP_COPP_API int start(void *priv_data = nullptr);
116
117# if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
124 LIBCOPP_COPP_API int start(std::exception_ptr &unhandled, void *priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
125# endif
126
133 LIBCOPP_COPP_API int resume(void *priv_data = nullptr);
134
135# if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
142 LIBCOPP_COPP_API int resume(std::exception_ptr &unhandled, void *priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
143# endif
144
150 LIBCOPP_COPP_API int yield(void **priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
151
160 template <class TAWAITABLE, class TERROR_TRANSFORM,
161 class = nostd::enable_if_t<stackful_inject_awaitable<nostd::remove_cvref_t<TAWAITABLE>>::value>>
162 LIBCOPP_COPP_API_HEAD_ONLY inline container_value_type<TAWAITABLE>
163 await_value(TAWAITABLE &&awaitable, TERROR_TRANSFORM &&error_transform) noexcept(
164 std::is_nothrow_copy_constructible<container_value_type<TAWAITABLE>>::value &&
165 noexcept(error_transform(COPP_EC_ARGS_ERROR))) {
166 return awaitable.inject_await(this, std::forward<TERROR_TRANSFORM>(error_transform));
167 }
168
177 template <class TAWAITABLE,
178 class = nostd::enable_if_t<stackful_inject_awaitable<nostd::remove_cvref_t<TAWAITABLE>>::value>>
179 LIBCOPP_COPP_API_HEAD_ONLY inline container_value_type<TAWAITABLE> await_value(TAWAITABLE &&awaitable) noexcept(
180 std::is_nothrow_copy_constructible<container_value_type<TAWAITABLE>>::value &&
182 return awaitable.inject_await(this, stackful_channel_error_transform<container_value_type<TAWAITABLE>>());
183 }
184};
185
186namespace this_fiber {
192LIBCOPP_COPP_API coroutine_context_fiber *get_coroutine() LIBCOPP_MACRO_NOEXCEPT;
193
200template <typename Tc>
201LIBCOPP_COPP_API_HEAD_ONLY Tc *get() {
202 return static_cast<Tc *>(get_coroutine());
203}
204
210LIBCOPP_COPP_API int yield(void **priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
211} // namespace this_fiber
212LIBCOPP_COPP_NAMESPACE_END
213
214#endif
base type of all coroutine context
LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< LIBCOPP_COPP_NAMESPACE_ID::util::lock::unsafe_int_type< int > > status_
std::function< int(void *)> callback_type
@ COPP_EC_ARGS_ERROR
COPP_EC_ARGS_ERROR.
Definition errno.h:30
STL namespace.
LIBCOPP_COPP_API int yield(void **priv_data=nullptr) LIBCOPP_MACRO_NOEXCEPT
yield current coroutine
LIBCOPP_COPP_API coroutine_context * get_coroutine() LIBCOPP_MACRO_NOEXCEPT
get current coroutine
typename nostd::remove_cvref_t< TCONTAINER >::value_type container_value_type
status of safe coroutine context base