libcopp  2.2.0
coroutine_context.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 
8 
9 #ifdef LIBCOPP_MACRO_USE_SEGMENTED_STACKS
10 # define COROUTINE_CONTEXT_BASE_USING_BASE_SEGMENTED_STACKS(base_type) using base_type::caller_stack_;
11 #else
12 # define COROUTINE_CONTEXT_BASE_USING_BASE_SEGMENTED_STACKS(base_type)
13 #endif
14 
15 #define COROUTINE_CONTEXT_BASE_USING_BASE(base_type) \
16  protected: \
17  using base_type::caller_; \
18  using base_type::callee_; \
19  using base_type::callee_stack_; \
20  COROUTINE_CONTEXT_BASE_USING_BASE_SEGMENTED_STACKS(base_type)
21 
22 LIBCOPP_COPP_NAMESPACE_BEGIN
27  public:
28  using ptr_type = LIBCOPP_COPP_NAMESPACE_ID::util::intrusive_ptr<coroutine_context>;
32 
33  // Compability with libcopp-1.x
34  using ptr_t = ptr_type;
37  using flag_t = flag_type;
38 
39  private:
46 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
47  using coroutine_context_base::unhandle_exception_;
48 #endif
49 
50  struct jump_src_data_t {
53  void *priv_data;
54  };
55 
56  friend struct libcopp_internal_api_set;
57 
58  protected:
63 #ifdef LIBCOPP_MACRO_USE_SEGMENTED_STACKS
64  stack_context caller_stack_;
65 #endif
66 
67  protected:
68  LIBCOPP_COPP_API coroutine_context() LIBCOPP_MACRO_NOEXCEPT;
69 
70  public:
71  LIBCOPP_COPP_API ~coroutine_context();
72 
73  private:
75  coroutine_context &operator=(const coroutine_context &) = delete;
77  coroutine_context &operator=(const coroutine_context &&) = delete;
78 
79  public:
88  static LIBCOPP_COPP_API int create(coroutine_context *p, callback_type &&runner, const stack_context &callee_stack,
89  size_t coroutine_size, size_t private_buffer_size) LIBCOPP_MACRO_NOEXCEPT;
90 
91  template <typename TRunner>
92  static LIBCOPP_COPP_API_HEAD_ONLY int create(coroutine_context *p, TRunner *runner, const stack_context &callee_stack,
93  size_t coroutine_size,
94  size_t private_buffer_size) LIBCOPP_MACRO_NOEXCEPT {
95  return create(
96  p, [runner](void *private_data) { return (*runner)(private_data); }, callee_stack, coroutine_size,
97  private_buffer_size);
98  }
99 
106  LIBCOPP_COPP_API int start(void *priv_data = nullptr);
107 
108 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
115  LIBCOPP_COPP_API int start(std::exception_ptr &unhandled, void *priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
116 #endif
117 
124  LIBCOPP_COPP_API int resume(void *priv_data = nullptr);
125 
126 #if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
133  LIBCOPP_COPP_API int resume(std::exception_ptr &unhandled, void *priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
134 #endif
135 
141  LIBCOPP_COPP_API int yield(void **priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
142 };
143 
144 namespace this_coroutine {
150 LIBCOPP_COPP_API coroutine_context *get_coroutine() LIBCOPP_MACRO_NOEXCEPT;
151 
158 template <typename Tc>
159 LIBCOPP_COPP_API_HEAD_ONLY Tc *get() {
160  return static_cast<Tc *>(get_coroutine());
161 }
162 
168 LIBCOPP_COPP_API int yield(void **priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
169 } // namespace this_coroutine
170 LIBCOPP_COPP_NAMESPACE_END
base type of all coroutine context
LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< int > status_
std::function< int(void *)> callback_type
base type of all stackful coroutine context
LIBCOPP_COPP_API coroutine_context() LIBCOPP_MACRO_NOEXCEPT
coroutine_context_base::flag_type flag_type
fcontext::fcontext_t caller_
stack_context callee_stack_
LIBCOPP_COPP_API int start(void *priv_data=nullptr)
start coroutine
LIBCOPP_COPP_API int yield(void **priv_data=nullptr) LIBCOPP_MACRO_NOEXCEPT
yield coroutine
callback_type callback_t
LIBCOPP_COPP_API int resume(void *priv_data=nullptr)
resume coroutine
LIBCOPP_COPP_NAMESPACE_ID::util::intrusive_ptr< coroutine_context > ptr_type
fcontext::fcontext_t callee_
coroutine_context_base::callback_type callback_type
static LIBCOPP_COPP_API int create(coroutine_context *p, callback_type &&runner, const stack_context &callee_stack, size_t coroutine_size, size_t private_buffer_size) LIBCOPP_MACRO_NOEXCEPT
create coroutine context at stack context callee_
coroutine_context_base::status_type status_type
LIBCOPP_COPP_API_HEAD_ONLY Tc * get()
get current coroutine and try to convert type
LIBCOPP_COPP_API coroutine_context * get_coroutine() LIBCOPP_MACRO_NOEXCEPT
get current coroutine
status of safe coroutine context base