Lely core libraries
2.2.5
|
Go to the documentation of this file.
40 #ifndef LELY_UTIL_FIBER_HPP_
41 #define LELY_UTIL_FIBER_HPP_
83 operator~(FiberFlag rhs) {
84 return static_cast<FiberFlag
>(~static_cast<int>(rhs));
87 constexpr FiberFlag operator&(FiberFlag lhs, FiberFlag rhs) {
88 return static_cast<FiberFlag
>(
static_cast<int>(lhs) &
static_cast<int>(rhs));
92 operator^(FiberFlag lhs, FiberFlag rhs) {
93 return static_cast<FiberFlag>(
static_cast<int>(lhs) ^
static_cast<int>(rhs));
97 operator|(FiberFlag lhs, FiberFlag rhs) {
98 return static_cast<FiberFlag>(
static_cast<int>(lhs) |
static_cast<int>(rhs));
102 operator&=(FiberFlag& lhs, FiberFlag rhs) {
103 return lhs = lhs & rhs;
107 operator^=(FiberFlag& lhs, FiberFlag rhs) {
108 return lhs = lhs ^ rhs;
112 operator|=(FiberFlag& lhs, FiberFlag rhs) {
113 return lhs = lhs | rhs;
121 bool terminated{
false};
123 ::std::exception_ptr eptr{
nullptr};
165 already = result != 0;
200 Fiber() noexcept =
default;
214 template <
class F,
class = typename ::std::enable_if<!::std::is_same<
215 typename ::std::decay<F>::type,
Fiber>::value>::type>
224 Fiber(F&& f, ::std::size_t stack_size)
225 :
Fiber(::std::forward<F>(f), static_cast<
FiberFlag>(0), stack_size) {}
244 &func_<decltype(f)>,
static_cast<void*
>(::std::addressof(f)),
247 auto data = data_(fiber_);
251 *
this = ::std::move(*this).resume();
253 auto eptr = data->eptr;
256 ::std::rethrow_exception(eptr);
291 auto data = data_(fiber_);
293 if (!data->terminated) {
295 *
this = ::std::move(*this).resume();
304 explicit operator bool() const noexcept {
return fiber_ !=
nullptr; }
306 operator fiber_t*() && noexcept {
350 f = (*
static_cast<F*
>(arg))(::std::move(f));
353 if (!data) data = FiberThread::data_();
354 data->eptr = ::std::current_exception();
356 return static_cast<fiber_t*
>(::std::move(f));
358 auto arg =
static_cast<void*
>(::std::addressof(f));
366 swap(fiber_, other.fiber_);
405 using F_ = typename ::std::decay<F>::type;
406 F_ func{::std::forward<F_>(
static_cast<F
>(*
static_cast<F_*
>(arg)))};
413 if (data->eptr) ::std::rethrow_exception(data->eptr);
415 if (!data->unwind) f = func(::std::move(f));
416 }
catch (fiber_unwind& e) {
417 f = ::std::move(e.f_);
419 data->terminated =
true;
420 return ::std::move(f);
425 data->eptr = ::std::current_exception();
435 Fiber::resume_(Fiber&& f) {
437 if (!data) data = FiberThread::data_();
442 auto eptr = data->eptr;
443 data->eptr =
nullptr;
445 if (data->unwind)
throw fiber_unwind(::std::move(f));
446 if (eptr) ::std::rethrow_exception(eptr);
448 return ::std::move(f);
454 #endif // !LELY_UTIL_FIBER_HPP_
fiber_t * fiber_create(fiber_func_t *func, void *arg, int flags, size_t data_size, size_t stack_size)
Creates a new fiber, allocates a stack and sets up a calling environment to begin executing the speci...
void * fiber_data(const fiber_t *fiber)
Returns a pointer to the data region of the specified fiber, or of the calling fiber if fiber is NULL...
void fiber_destroy(fiber_t *fiber)
Destroys the specified fiber.
FiberFlag
Specifies which properties of the calling environment are saved or restored by a fiber when it is sus...
Fiber(F &&f, FiberFlag flags, ::std::size_t stack_size)
Constructs a fiber with a newly allocated stack.
void swap(Fiber &other) noexcept
Swaps the states of *this and other.
void fiber_thrd_fini(void)
Finalizes the fiber associated with the calling thread.
Fiber resume_with(F &&f) &&
Suspends the calling fiber and resumes *this, but calls f(other) in the resumed fiber as if called by...
Fiber(Fiber &&other) noexcept
Moves the state of other to *this.
#define FIBER_SAVE_MASK
A flag specifying a fiber to save and restore the signal mask (only supported on POSIX platforms).
#define FIBER_GUARD_STACK
A flag specifying a fiber to add a guard page when allocating the stack frame so that the kernel gene...
void throw_errc(int errc=get_errc())
Throws an std::system_error exception corresponding to the specified or current (thread-specific) nat...
Convenience class providing a RAII-style mechanism to ensure the fiber associated with the calling th...
FiberThread(FiberFlag flags)
Initializes the fiber associated with the calling thread, if it was not already initialized.
#define FIBER_SAVE_ERROR
A flag specifying a fiber to save and restore the error values (i.e., errno and GetLastError() on Win...
The exception used by lely::util::Fiber::~Fiber() to terminate the callable object and unwind its sta...
Determines whether F can be invoked with the arguments Args... to yield a result that is convertable ...
fiber_t * fiber_resume(fiber_t *fiber)
Equivalent to fiber_resume_with(fiber, NULL, NULL).
Fiber(F &&f, FiberFlag flags)
Equivalent to Fiber::Fiber(f, flags, 0).
Fiber(F &&f)
Equivalent to Fiber::Fiber(f, static_cast<FiberFlag>(0), 0).
~Fiber()
Destroys a Fiber instance.
Fiber resume() &&
Suspends the calling fiber and resumes *this.
Fiber & operator=(Fiber &&other) noexcept
Moves the state of other to *this.
~FiberThread()
Finalizes the fiber associated with the calling thread, unless another instance of this class is stil...
FiberThread()
Equivalent to #FiberThread(static_cast<FiberFlag>(0)).
fiber_t * fiber_resume_with(fiber_t *fiber, fiber_func_t *func, void *arg)
Suspends the calling fiber and resumes the specified fiber, optionally executing a function before re...
Fiber(F &&f, ::std::size_t stack_size)
Equivalent to Fiber::Fiber(f, static_cast<FiberFlag>(0), stack_size).
FiberThread(FiberFlag flags, bool &already)
Initializes the fiber associated with the calling thread, if it was not already initialized.
int fiber_thrd_init(int flags)
Initializes the fiber associated with the calling thread.
#define FIBER_SAVE_ALL
A combination of those flags in FIBER_SAVE_MASK, FIBER_SAVE_FENV and FIBER_SAVE_ERROR that are suppor...
#define FIBER_SAVE_FENV
A flag specifying a fiber to save and restore the floating-point environment.
Fiber() noexcept=default
Creates an invalid fiber.