libcopp  2.2.0
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>
6 
7 // clang-format off
8 #include <libcopp/utils/config/stl_include_prefix.h> // NOLINT(build/include_order)
9 // clang-format on
10 #include <cstddef>
11 // clang-format off
12 #include <libcopp/utils/config/stl_include_suffix.h> // NOLINT(build/include_order)
13 // clang-format on
14 
15 #include "coroutine_context.h"
16 
17 #if defined(LIBCOPP_MACRO_ENABLE_WIN_FIBER) && LIBCOPP_MACRO_ENABLE_WIN_FIBER
18 
19 # ifndef WIN32_LEAN_AND_MEAN
20 # define WIN32_LEAN_AND_MEAN
21 # endif
22 
23 # include <Windows.h> // NOLINT(build/include_order)
24 
25 LIBCOPP_COPP_NAMESPACE_BEGIN
29 class coroutine_context_fiber : public coroutine_context_base {
30  public:
31  using ptr_type = LIBCOPP_COPP_NAMESPACE_ID::util::intrusive_ptr<coroutine_context_fiber>;
32 
33  using callback_type = coroutine_context_base::callback_type;
34  using status_type = coroutine_context_base::status_type;
35  using flag_type = coroutine_context_base::flag_type;
36 
37  // Compability with libcopp-1.x
38  using ptr_t = ptr_type;
39  using callback_t = callback_type;
40  using status_t = status_type;
41  using flag_t = flag_type;
42 
43  private:
50 # if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
51  using coroutine_context_base::unhandle_exception_;
52 # endif
53 
54  struct jump_src_data_t {
55  coroutine_context_fiber *from_co;
56  LPVOID from_fiber;
57  coroutine_context_fiber *to_co;
58  LPVOID to_fiber;
59  void *priv_data;
60  };
61 
62  friend struct LIBCOPP_COPP_API_HEAD_ONLY libcopp_fiber_internal_api_set;
63  friend struct LIBCOPP_COPP_API_HEAD_ONLY fiber_context_tls_data_t;
64 
65  protected:
66  LPVOID caller_;
67  LPVOID callee_;
69  stack_context callee_stack_;
71  protected:
72  LIBCOPP_COPP_API coroutine_context_fiber() LIBCOPP_MACRO_NOEXCEPT;
73 
74  public:
75  LIBCOPP_COPP_API ~coroutine_context_fiber();
76 
77  private:
78  coroutine_context_fiber(const coroutine_context_fiber &) = delete;
79  coroutine_context_fiber &operator=(const coroutine_context_fiber &) = delete;
80  coroutine_context_fiber(const coroutine_context_fiber &&) = delete;
81  coroutine_context_fiber &operator=(const coroutine_context_fiber &&) = delete;
82 
83  public:
92  static LIBCOPP_COPP_API int create(coroutine_context_fiber *p, callback_type &&runner,
93  const stack_context &callee_stack, size_t coroutine_size,
94  size_t private_buffer_size,
95  size_t stack_reserve_size_of_fiber = 0) LIBCOPP_MACRO_NOEXCEPT;
96 
97  template <typename TRunner>
98  static LIBCOPP_COPP_API_HEAD_ONLY int create(coroutine_context_fiber *p, TRunner *runner,
99  const stack_context &callee_stack, size_t coroutine_size,
100  size_t private_buffer_size,
101  size_t stack_reserve_size_of_fiber = 0) LIBCOPP_MACRO_NOEXCEPT {
102  return create(
103  p, [runner](void *private_data) { return (*runner)(private_data); }, callee_stack, coroutine_size,
104  private_buffer_size, stack_reserve_size_of_fiber);
105  }
106 
113  LIBCOPP_COPP_API int start(void *priv_data = nullptr);
114 
115 # if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
122  LIBCOPP_COPP_API int start(std::exception_ptr &unhandled, void *priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
123 # endif
124 
131  LIBCOPP_COPP_API int resume(void *priv_data = nullptr);
132 
133 # if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
140  LIBCOPP_COPP_API int resume(std::exception_ptr &unhandled, void *priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
141 # endif
142 
148  LIBCOPP_COPP_API int yield(void **priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
149 };
150 
151 namespace this_fiber {
157 LIBCOPP_COPP_API coroutine_context_fiber *get_coroutine() LIBCOPP_MACRO_NOEXCEPT;
158 
165 template <typename Tc>
166 LIBCOPP_COPP_API_HEAD_ONLY Tc *get() {
167  return static_cast<Tc *>(get_coroutine());
168 }
169 
175 LIBCOPP_COPP_API int yield(void **priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
176 } // namespace this_fiber
177 LIBCOPP_COPP_NAMESPACE_END
178 
179 #endif
base type of all coroutine context
LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< int > status_
std::function< int(void *)> callback_type
LIBCOPP_COPP_API_HEAD_ONLY Tc * get()
get current coroutine and try to convert type
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
status of safe coroutine context base