Zth (libzth)
Loading...
Searching...
No Matches
async.h
Go to the documentation of this file.
1#ifndef ZTH_ASYNC_H
2#define ZTH_ASYNC_H
3/*
4 * SPDX-FileCopyrightText: 2019-2026 Jochem Rutgers
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 */
8
9#include <libzth/macros.h>
10
11#ifdef __cplusplus
12
13# include <libzth/allocator.h>
14# include <libzth/config.h>
15# include <libzth/exception.h>
16# include <libzth/fiber.h>
17# include <libzth/sync.h>
18# include <libzth/util.h>
19# include <libzth/worker.h>
20
21# if __cplusplus >= 201103L
22# include <initializer_list>
23# include <tuple>
24# include <type_traits>
25# endif
26
27# if __cplusplus < 201103L
28# undef ZTH_TYPEDFIBER98
29// Always use C++98-compatible TypedFiber implementation.
30# define ZTH_TYPEDFIBER98 1
31# elif !defined(ZTH_TYPEDFIBER98)
32// By default only use C++11 TypedFiber implementation, but this can be
33// overridden for testing purposes.
34# define ZTH_TYPEDFIBER98 0
35# endif
36
37namespace zth {
38
39
40
42// Typed fiber base class and manipulators
43//
44
54template <typename R>
55class TypedFiber : public Fiber {
57public:
58 typedef R Return;
60
61 constexpr TypedFiber()
62 : Fiber(&entry, this)
63 {}
64
65 virtual ~TypedFiber() noexcept override is_default
66
68 {
69 m_future.reset(future);
70 zth_dbg(sync, "[%s] Registered to %s", future->id_str(), id_str());
71
72 if(state() == Fiber::Dead) {
73 // Fiber already dead, set the future now.
74# ifdef ZTH_FUTURE_EXCEPTION
75 setFuture(std::make_exception_ptr(fiber_already_dead()));
76# else
77 setFuture();
78# endif
79 }
80 }
81
83 {
84 return m_future;
85 }
86
88 {
89 if(!m_future.get()) {
92 ? new Future_type()
93 : new Future_type(
94 format("Future of %s", this->name().c_str())
95 .c_str()));
96 }
97
98 return m_future;
99 }
100
102 {
103 return withFuture();
104 }
105
107 {
108 return withFuture();
109 }
110
111protected:
112 static void entry(void* that)
113 {
114 if(unlikely(!that))
115 return;
116
117 TypedFiber& f = *static_cast<TypedFiber*>(that);
118
119# ifdef ZTH_FUTURE_EXCEPTION
120 try {
121# endif // ZTH_FUTURE_EXCEPTION
122 f.entry_();
123# ifdef ZTH_FUTURE_EXCEPTION
124 } catch(...) {
125 f.setFuture(std::current_exception());
126 }
127# endif // ZTH_FUTURE_EXCEPTION
128 }
129
130 virtual void entry_() = 0;
131
132 template <typename T>
133 void setFuture(T const& r)
134 {
135 if(m_future.get())
136 m_future->set(r);
137 }
138
140 {
141 if(m_future.get())
142 m_future->set();
143 }
144
145# ifdef ZTH_FUTURE_EXCEPTION
146 void setFuture(std::exception_ptr exception)
147 {
148 if(m_future.get())
149 m_future->set(std::move(exception));
150 }
151# endif // ZTH_FUTURE_EXCEPTION
152private:
153 SharedPointer<Future_type> m_future;
154};
155
157
176 size_t stack;
177
178 constexpr explicit setStackSize(size_t s) noexcept
179 : stack(s)
180 {}
181};
182
183template <typename R>
184TypedFiber<R>& operator<<(TypedFiber<R>& fiber, setStackSize const& m)
185{
186 if(m.stack) {
187 int res = fiber.setStackSize(m.stack);
188 if(res)
189 zth_throw(errno_exception(res));
190 }
191
192 return fiber;
193}
194
201struct setName : public FiberManipulator {
202# if __cplusplus >= 201103L
203 explicit setName(char const* n)
204 : name(n ? std::string{n} : std::string{})
205 {}
206
207 explicit setName(string const& n)
208 : name(n)
209 {}
210 explicit setName(string&& n)
211 : name(std::move(n))
212 {}
213# else // Pre C++11
214 explicit setName(char const* n)
215 : name(n)
216 {}
217
218 explicit setName(string const& n)
219 : name(n.c_str())
220 {}
221# endif // Pre C++11
222
223# if __cplusplus >= 201103L
224 string name;
225# else
226 char const* name;
227# endif
228};
229
230template <typename R>
232{
233 fiber.setName(m.name);
234 return fiber;
235}
236
237# if __cplusplus >= 201103L
238template <typename R>
239TypedFiber<R>& operator<<(TypedFiber<R>& fiber, setName&& m)
240{
241 fiber.setName(std::move(m.name));
242 return fiber;
243}
244# endif // C++11
245
267public:
268 constexpr explicit passOnExit(Gate& g) noexcept
269 : gate(g)
270 {}
271
272 static void atExit(Fiber& UNUSED_PAR(f), void* g) noexcept
273 {
274 static_cast<Gate*>(g)->pass();
275 }
276
278};
279
280static inline Fiber& operator<<(Fiber& fiber, passOnExit const& m)
281{
282 fiber.atExit(&passOnExit::atExit, static_cast<void*>(&m.gate));
283 return fiber;
284}
285
286template <typename R>
287TypedFiber<R>& operator<<(TypedFiber<R>& fiber, passOnExit const& m)
288{
289 static_cast<Fiber&>(fiber) << m;
290 return fiber;
291}
292
310struct asFuture : public FiberManipulator {};
311
312template <typename R>
314operator<<(TypedFiber<R>& fiber, asFuture const&)
315{
316 return fiber.withFuture();
317}
318
319
320
322// Actual TypedFiber implementations
323//
324// The TypedFiberX classes hold the actual entry point and arguments for the fiber. For Pre-C++11,
325// up to 3 arguments are supported. For C++11 and later, arbitrary arguments are supported.
326//
327
328# if ZTH_TYPEDFIBER98
329template <typename R>
330class TypedFiber0 final : public TypedFiber<R> {
331 ZTH_CLASS_NEW_DELETE(TypedFiber0)
332public:
333 typedef TypedFiber<R> base;
334 typedef R (*Function)();
335
336 explicit TypedFiber0(Function function)
337 : m_function(function)
338 {}
339
340 virtual ~TypedFiber0() final is_default
341
342protected:
343 virtual void entry_() final
344 {
345 this->setFuture(m_function());
346 }
347
348private:
349 Function m_function;
350};
351
352template <>
353class TypedFiber0<void> final : public TypedFiber<void> {
354 ZTH_CLASS_NEW_DELETE(TypedFiber0)
355public:
356 typedef TypedFiber<void> base;
357 typedef void (*Function)();
358
359 explicit TypedFiber0(Function func)
360 : m_function(func)
361 {}
362
363 virtual ~TypedFiber0() noexcept final is_default
364
365protected:
366 virtual void entry_() final
367 {
368 m_function();
369 this->setFuture();
370 }
371
372private:
373 Function m_function;
374};
375
376template <typename R, typename A1>
377class TypedFiber1 final : public TypedFiber<R> {
378 ZTH_CLASS_NEW_DELETE(TypedFiber1)
379public:
380 typedef TypedFiber<R> base;
381 typedef R (*Function)(A1);
382
383 TypedFiber1(Function func, A1 a1)
384 : m_function(func)
385 , m_a1(a1)
386 {}
387
388 virtual ~TypedFiber1() noexcept final is_default
389
390protected:
391 virtual void entry_() final
392 {
393 this->setFuture(m_function(m_a1));
394 }
395
396private:
397 Function m_function;
398 A1 m_a1;
399};
400
401template <typename A1>
402class TypedFiber1<void, A1> final : public TypedFiber<void> {
403 ZTH_CLASS_NEW_DELETE(TypedFiber1)
404public:
405 typedef TypedFiber<void> base;
406 typedef void (*Function)(A1);
407
408 // cppcheck-suppress uninitMemberVar
409 TypedFiber1(Function func, A1 a1)
410 : m_function(func)
411 , m_a1(a1)
412 {}
413
414 virtual ~TypedFiber1() noexcept final is_default
415
416protected:
417 virtual void entry_() final
418 {
419 m_function(m_a1);
420 this->setFuture();
421 }
422
423private:
424 Function m_function;
425 A1 m_a1;
426};
427
428template <typename R, typename A1, typename A2>
429class TypedFiber2 final : public TypedFiber<R> {
430 ZTH_CLASS_NEW_DELETE(TypedFiber2)
431public:
432 typedef TypedFiber<R> base;
433 typedef R (*Function)(A1, A2);
434
435 TypedFiber2(Function func, A1 a1, A2 a2)
436 : m_function(func)
437 , m_a1(a1)
438 , m_a2(a2)
439 {}
440
441 virtual ~TypedFiber2() noexcept final is_default
442
443protected:
444 virtual void entry_() final
445 {
446 this->setFuture(m_function(m_a1, m_a2));
447 }
448
449private:
450 Function m_function;
451 A1 m_a1;
452 A2 m_a2;
453};
454
455template <typename A1, typename A2>
456class TypedFiber2<void, A1, A2> final : public TypedFiber<void> {
457 ZTH_CLASS_NEW_DELETE(TypedFiber2)
458public:
459 typedef TypedFiber<void> base;
460 typedef void (*Function)(A1, A2);
461
462 // cppcheck-suppress uninitMemberVar
463 TypedFiber2(Function func, A1 a1, A2 a2)
464 : m_function(func)
465 , m_a1(a1)
466 , m_a2(a2)
467 {}
468
469 virtual ~TypedFiber2() noexcept final is_default
470
471protected:
472 virtual void entry_() final
473 {
474 m_function(m_a1, m_a2);
475 this->setFuture();
476 }
477
478private:
479 Function m_function;
480 A1 m_a1;
481 A2 m_a2;
482};
483
484template <typename R, typename A1, typename A2, typename A3>
485class TypedFiber3 final : public TypedFiber<R> {
486 ZTH_CLASS_NEW_DELETE(TypedFiber3)
487public:
488 typedef TypedFiber<R> base;
489 typedef R (*Function)(A1, A2, A3);
490
491 TypedFiber3(Function func, A1 a1, A2 a2, A3 a3)
492 : m_function(func)
493 , m_a1(a1)
494 , m_a2(a2)
495 , m_a3(a3)
496 {}
497
498 virtual ~TypedFiber3() noexcept final is_default
499
500protected:
501 virtual void entry_() final
502 {
503 this->setFuture(m_function(m_a1, m_a2, m_a3));
504 }
505
506private:
507 Function m_function;
508 A1 m_a1;
509 A2 m_a2;
510 A3 m_a3;
511};
512
513template <typename A1, typename A2, typename A3>
514class TypedFiber3<void, A1, A2, A3> final : public TypedFiber<void> {
515 ZTH_CLASS_NEW_DELETE(TypedFiber3)
516public:
517 typedef TypedFiber<void> base;
518 typedef void (*Function)(A1, A2, A3);
519
520 // cppcheck-suppress uninitMemberVar
521 TypedFiber3(Function func, A1 a1, A2 a2, A3 a3)
522 : m_function(func)
523 , m_a1(a1)
524 , m_a2(a2)
525 , m_a3(a3)
526 {}
527
528 virtual ~TypedFiber3() noexcept final is_default
529
530protected:
531 virtual void entry_() final
532 {
533 m_function(m_a1, m_a2, m_a3);
534 this->setFuture();
535 }
536
537private:
538 Function m_function;
539 A1 m_a1;
540 A2 m_a2;
541 A3 m_a3;
542};
543# endif // ZTH_TYPEDFIBER98
544
545# if __cplusplus >= 201103L
546// Always try to move the argument, unless it's an lvalue reference.
547template <typename T, typename std::enable_if<!std::is_lvalue_reference<T>::value, int>::type = 0>
548static constexpr T&& move_or_ref(T& t) noexcept
549{
550 return std::move(t);
551}
552
553template <typename T, typename std::enable_if<std::is_lvalue_reference<T>::value, int>::type = 0>
554static constexpr T move_or_ref(T t) noexcept
555{
556 return t;
557}
558
565template <typename F, typename R, typename Args>
566class TypedFiberN final : public TypedFiber<R> {
568public:
570 using Function = F;
571
572 template <typename F_, typename... Args_>
573 TypedFiberN(F_&& func, Args_&&... args)
574 : m_function{std::forward<F_>(func)}
575 , m_args{std::forward<Args_>(args)...}
576 {}
577
578 virtual ~TypedFiberN() final = default;
579
580protected:
581 virtual void entry_() final
582 {
583 entry__(typename SequenceGenerator<std::tuple_size<Args>::value>::type());
584 }
585
586private:
587 template <size_t... S>
588 void entry__(Sequence<S...>)
589 {
590 this->setFuture(m_function(move_or_ref<typename std::tuple_element<S, Args>::type>(
591 std::get<S>(m_args))...));
592 }
593
594private:
595 Function m_function;
596 Args m_args;
597};
598
599template <typename F, typename Args>
600class TypedFiberN<F, void, Args> final : public TypedFiber<void> {
602public:
604 using Function = F;
605
606 template <typename F_, typename... Args_>
607 TypedFiberN(F_&& func, Args_&&... args)
608 : m_function{std::forward<F_>(func)}
609 , m_args{std::forward<Args_>(args)...}
610 {}
611
612 virtual ~TypedFiberN() final = default;
613
614protected:
615 virtual void entry_() final
616 {
617 entry__(typename SequenceGenerator<std::tuple_size<Args>::value>::type());
618 }
619
620private:
621 template <size_t... S>
622 void entry__(Sequence<S...>)
623 {
624 m_function(move_or_ref<typename std::tuple_element<S, Args>::type>(
625 std::get<S>(m_args))...);
626 this->setFuture();
627 }
628
629private:
630 Function m_function;
631 Args m_args;
632};
633# endif // C++11
634
635
636
638// Define TypedFiberType to extract function type information to pick the right TypedFiberX class.
639//
640
641template <typename F>
643 typedef F type;
644};
645
646# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_(P, PArgs, suffix, ...) \
647 template <typename R, ##__VA_ARGS__> \
648 struct remove_function_cvref<R P PArgs suffix> { \
649 typedef R(type) PArgs; \
650 };
651
652# if ZTH_TYPEDFIBER98
653# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A0(P, suffix) \
654 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_(P, (), suffix)
655# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A1(P, suffix) \
656 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_(P, (A1), suffix, typename A1)
657# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A2(P, suffix) \
658 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_(P, (A1, A2), suffix, typename A1, typename A2)
659# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A3(P, suffix) \
660 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_( \
661 P, (A1, A2, A3), suffix, typename A1, typename A2, typename A3)
662
663# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A(P, suffix) \
664 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A0(P, suffix) \
665 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A1(P, suffix) \
666 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A2(P, suffix) \
667 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A3(P, suffix)
668# else
669# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A(P, suffix)
670# endif // ZTH_TYPEDFIBER98
671
672# if __cplusplus >= 201103L
673# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS(P, suffix) \
674 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A(P, suffix) \
675 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_(P, (Args...), suffix, typename... Args)
676# else
677# define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS(P, suffix) \
678 REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A(P, suffix)
679# endif // C++11
680
685
686# if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
691# endif // __cpp_noexcept_function_type
692
693# undef REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_
694# undef REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A0
695# undef REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A1
696# undef REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A2
697# undef REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A3
698# undef REMOVE_FUNCTION_CVREF_SPECIALIZATIONS_A
699# undef REMOVE_FUNCTION_CVREF_SPECIALIZATIONS
700
701# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_(PArgs, cvref, ...) \
702 template <typename R, typename C, ##__VA_ARGS__> \
703 struct remove_function_cvref<R(C::*) PArgs cvref> { \
704 typedef R(type) PArgs; \
705 };
706
707# if ZTH_TYPEDFIBER98
708# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A0(cvref) \
709 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_((), cvref)
710# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A1(cvref) \
711 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_((A1), cvref, typename A1)
712# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A2(cvref) \
713 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_((A1, A2), cvref, typename A1, typename A2)
714# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A3(cvref) \
715 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_( \
716 (A1, A2, A3), cvref, typename A1, typename A2, typename A3)
717# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A(cvref) \
718 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A0(cvref) \
719 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A1(cvref) \
720 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A2(cvref) \
721 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A3(cvref)
722# else
723# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A(cvref)
724# endif // ZTH_TYPEDFIBER98
725
726# if __cplusplus >= 201103L
727# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS(cvref) \
728 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A(cvref) \
729 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_((Args...), cvref, typename... Args)
730# else
731# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS(cvref) \
732 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A(cvref)
733# endif // C++11
734
735# define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_CV(...) \
736 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS(__VA_ARGS__) \
737 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS(const __VA_ARGS__) \
738 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS(volatile __VA_ARGS__) \
739 REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS(const volatile __VA_ARGS__)
740
742# if __cplusplus >= 201103L
745
746# if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
750# endif // __cpp_noexcept_function_type
751# endif // C++11
752
753# undef REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_
754# undef REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A0
755# undef REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A1
756# undef REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A2
757# undef REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A3
758# undef REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_A
759# undef REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS
760# undef REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_CV
761
762# if __cplusplus >= 201103L
763template <typename T>
765
766template <typename R, typename... Args>
767struct functor_operator_type<R(Args...)> {
768 using return_type = R;
769 using args_type = std::tuple<Args...>;
770};
771
772// Extract function type from functor's operator().
773template <typename F>
775 using functor_type = typename std::decay<F>::type;
776
777private:
779 typename remove_function_cvref<decltype(&functor_type::operator())>::type>;
780
781public:
782 using return_type = typename functor_operator_type_::return_type;
783 using args_type = typename functor_operator_type_::args_type;
784};
785
786// Extract function type from function pointer.
787template <typename R, typename... Args>
788struct functor_traits<R (*)(Args...)> {
789public:
790 using functor_type = R (*)(Args...);
791 using return_type = R;
792 using args_type = std::tuple<Args...>;
793};
794
795template <typename R, typename... Args>
796struct functor_traits<R (*&)(Args...)> {
797public:
798 using functor_type = R (*)(Args...);
799 using return_type = R;
800 using args_type = std::tuple<Args...>;
801};
802
803// Extract function type from function reference.
804template <typename R, typename... Args>
805struct functor_traits<R (&)(Args...)> {
806public:
807 using functor_type = R (&)(Args...);
808 using return_type = R;
809 using args_type = std::tuple<Args...>;
810};
811
812// Extract function type from function type.
813template <typename R, typename... Args>
814struct functor_traits<R(Args...)> {
815public:
816 using functor_type = R (*)(Args...);
817 using return_type = R;
818 using args_type = std::tuple<Args...>;
819};
820
821// Extract fiber function type information.
822template <typename F>
834# else // Pre C++11
835template <typename F>
836struct TypedFiberType {};
837# endif // Pre C++11
838
839# if ZTH_TYPEDFIBER98
840# define ZTH_TYPEDFIBERTYPE_SPECIALIZATION(P) \
841 template <typename R> \
842 struct TypedFiberType<R P()> { \
843 struct NoArg {}; \
844 typedef R returnType; \
845 typedef TypedFiber0<R> fiberType; \
846 typedef NoArg a1Type; \
847 typedef NoArg a2Type; \
848 typedef NoArg a3Type; \
849 }; \
850 \
851 template <typename R, typename A1> \
852 struct TypedFiberType<R P(A1)> { \
853 struct NoArg {}; \
854 typedef R returnType; \
855 typedef TypedFiber1<R, A1> fiberType; \
856 typedef A1 a1Type; \
857 typedef NoArg a2Type; \
858 typedef NoArg a3Type; \
859 }; \
860 \
861 template <typename R, typename A1, typename A2> \
862 struct TypedFiberType<R P(A1, A2)> { \
863 struct NoArg {}; \
864 typedef R returnType; \
865 typedef TypedFiber2<R, A1, A2> fiberType; \
866 typedef A1 a1Type; \
867 typedef A2 a2Type; \
868 typedef NoArg a3Type; \
869 }; \
870 \
871 template <typename R, typename A1, typename A2, typename A3> \
872 struct TypedFiberType<R P(A1, A2, A3)> { \
873 struct NoArg {}; \
874 typedef R returnType; \
875 typedef TypedFiber3<R, A1, A2, A3> fiberType; \
876 typedef A1 a1Type; \
877 typedef A2 a2Type; \
878 typedef A3 a3Type; \
879 };
880
881ZTH_TYPEDFIBERTYPE_SPECIALIZATION()
882ZTH_TYPEDFIBERTYPE_SPECIALIZATION((*))
883ZTH_TYPEDFIBERTYPE_SPECIALIZATION((*&))
884ZTH_TYPEDFIBERTYPE_SPECIALIZATION((&))
885
886# undef ZTH_TYPEDFIBERTYPE_SPECIALIZATION
887# endif // ZTH_TYPEDFIBER98
888
889
890
892// Define a TypedFiberFactory. It holds the entry function and creates fibers when the arguments are
893// passed. The entry function and name are stored in the factory, the arguments are passed directly
894// to the new fiber (managed by TypedFiberX).
895//
896
897template <typename F>
899 typedef F type;
900};
901
902# if ZTH_TYPEDFIBER98
903# define FUNCTION_TYPE_HELPER_SPECIALIZATION(P) \
904 template <typename R> \
905 struct function_type_helper<R P()> { \
906 typedef R (*type)(); \
907 }; \
908 \
909 template <typename R, typename A1> \
910 struct function_type_helper<R P(A1)> { \
911 typedef R (*type)(A1); \
912 }; \
913 \
914 template <typename R, typename A1, typename A2> \
915 struct function_type_helper<R P(A1, A2)> { \
916 typedef R (*type)(A1, A2); \
917 }; \
918 \
919 template <typename R, typename A1, typename A2, typename A3> \
920 struct function_type_helper<R P(A1, A2, A3)> { \
921 typedef R (*type)(A1, A2, A3); \
922 };
923
924FUNCTION_TYPE_HELPER_SPECIALIZATION()
925FUNCTION_TYPE_HELPER_SPECIALIZATION((*))
926FUNCTION_TYPE_HELPER_SPECIALIZATION((*&))
927FUNCTION_TYPE_HELPER_SPECIALIZATION((&))
928
929# undef FUNCTION_TYPE_HELPER_SPECIALIZATION
930# endif // ZTH_TYPEDFIBER98
931
932# if __cplusplus >= 201103L
933template <typename R, typename... Args>
934struct function_type_helper<R(Args...)> {
935 using type = R (*)(Args...);
936};
937
938template <typename R, typename... Args>
939struct function_type_helper<R (*)(Args...)> {
940 using type = R (*)(Args...);
941};
942
943template <typename R, typename... Args>
944struct function_type_helper<R (*&)(Args...)> {
945 using type = R (*)(Args...);
946};
947
948template <typename R, typename... Args>
949struct function_type_helper<R (&)(Args...)> {
950 using type = R (*)(Args...);
951};
952# endif // C++11
953
954template <typename F>
955struct fiber_type;
956
957template <typename F>
959public:
964
965 constexpr TypedFiberFactory(Function function, char const* name) noexcept
966 : m_function(function)
967 , m_name(name)
968 {}
969
970# if __cplusplus >= 201103L
971 template <typename F_>
972 constexpr TypedFiberFactory(F_&& function, char const* name) noexcept
973 : m_function{std::forward<F_>(function)}
974 , m_name{name}
975 {}
976# endif // C++11
977
978# if ZTH_TYPEDFIBER98
979 typedef typename TypedFiberType<Function>::a1Type A1;
980 typedef typename TypedFiberType<Function>::a2Type A2;
981 typedef typename TypedFiberType<Function>::a3Type A3;
982
983 fiber_type<Function> operator()() const
984 {
985 return polish(*new TypedFiber_type(m_function));
986 }
987
988 fiber_type<Function> operator()(A1 a1) const
989 {
990 return polish(*new TypedFiber_type(m_function, a1));
991 }
992
993 fiber_type<Function> operator()(A1 a1, A2 a2) const
994 {
995 return polish(*new TypedFiber_type(m_function, a1, a2));
996 }
997
998 fiber_type<Function> operator()(A1 a1, A2 a2, A3 a3) const
999 {
1000 return polish(*new TypedFiber_type(m_function, a1, a2, a3));
1001 }
1002# endif // ZTH_TYPEDFIBER98
1003
1004# if __cplusplus >= 201103L
1005 template <typename... Args>
1006 fiber_type<Function> operator()(Args&&... args) const
1007 {
1008 return polish(*new TypedFiber_type{m_function, std::forward<Args>(args)...});
1009 }
1010# endif // C++11
1011
1012protected:
1014 {
1015 if(unlikely(m_name))
1016 fiber.setName(m_name);
1017
1019 return fiber;
1020 }
1021
1022private:
1023 Function m_function;
1024 char const* m_name;
1025};
1026
1027
1028
1030// Provide a zth::fiber_type<F> API to get fiber information.
1031//
1032
1033template <typename F>
1036 typedef typename factory::Function function;
1037 typedef typename factory::Future future;
1039
1042
1043 // cppcheck-suppress noExplicitConstructor
1045 : _fiber(&f)
1046 {}
1047
1049 {
1050 future f = _fiber->withFuture();
1051 f.get().wait();
1052 return *f;
1053 }
1054
1056 {
1057 future f = _fiber->withFuture();
1058 f.get().wait();
1059 return *f;
1060 }
1061
1062 operator TypedFiber_type&() const noexcept
1063 {
1064 return *_fiber;
1065 }
1066
1067 operator Fiber&() const noexcept
1068 {
1069 return *_fiber;
1070 }
1071
1072 operator future() const noexcept
1073 {
1074 return _fiber->withFuture();
1075 }
1076
1077 template <typename Manipulator>
1078 fiber& operator<<(Manipulator const& m) LREF_QUALIFIED
1079 {
1080 *_fiber << m;
1081 return *this;
1082 }
1083
1084 template <typename Manipulator>
1085 fiber const& operator<<(Manipulator const& m) const
1086 {
1087 *_fiber << m;
1088 return *this;
1089 }
1090
1091# if __cplusplus >= 201103L
1092 template <typename Manipulator>
1093 fiber&& operator<<(Manipulator const& m) &&
1094 {
1095 *_fiber << m;
1096 return std::move(*this);
1097 }
1098# endif // C++11
1099
1101 {
1102 return *_fiber << asFuture();
1103 }
1104};
1105
1106
1107
1109// zth::factory() and zth::fiber() functions
1110//
1111
1112namespace impl {
1113static inline char const* fiber_name(char const* name)
1114{
1116 ? name
1117 : nullptr;
1118}
1119} // namespace impl
1120
1121# if __cplusplus >= 201103L
1130template <typename F>
1131typename fiber_type<F>::factory factory(F&& f, char const* name = nullptr)
1132{
1133 return typename fiber_type<F>::factory(std::forward<F>(f), impl::fiber_name(name));
1134}
1135
1136template <typename F>
1137typename fiber_type<F>::factory factory(F const& f, char const* name = nullptr)
1138{
1139 return typename fiber_type<F>::factory(f, impl::fiber_name(name));
1140}
1141# else // Pre-C++11
1142template <typename F>
1143typename fiber_type<F>::factory factory(F f, char const* name = nullptr)
1144{
1145 return typename fiber_type<F>::factory(f, impl::fiber_name(name));
1146}
1147# endif // Pre-C++11
1148
1149# if ZTH_TYPEDFIBER98
1150template <typename F>
1151typename fiber_type<F>::fiber fiber(F f)
1152{
1153 return factory<F>(f)();
1154}
1155
1156template <typename F>
1157typename fiber_type<F>::fiber fiber(F f, typename fiber_type<F>::factory::A1 a1)
1158{
1159 return factory<F>(f)(a1);
1160}
1161
1162template <typename F>
1163typename fiber_type<F>::fiber
1164fiber(F f, typename fiber_type<F>::factory::A1 a1, typename fiber_type<F>::factory::A2 a2)
1165{
1166 return factory<F>(f)(a1, a2);
1167}
1168
1169template <typename F>
1170typename fiber_type<F>::fiber
1171fiber(F f, typename fiber_type<F>::factory::A1 a1, typename fiber_type<F>::factory::A2 a2,
1172 typename fiber_type<F>::factory::A3 a3)
1173{
1174 return factory<F>(f)(a1, a2, a3);
1175}
1176# endif // ZTH_TYPEDFIBER98
1177
1178# if __cplusplus >= 201103L
1191template <typename F, typename... Args>
1192typename fiber_type<F>::fiber fiber(F&& f, Args&&... args)
1193{
1194 return factory<F>(std::forward<F>(f))(std::forward<Args>(args)...);
1195}
1196# endif // C++11
1197
1198
1199
1201// Simplify fiber future type access
1202//
1203
1204namespace impl {
1205template <typename F>
1207 enum { value = 0 };
1208};
1209
1210# if ZTH_TYPEDFIBER98
1211template <typename R>
1212struct is_function_<R()> {
1213 enum { value = 1 };
1214};
1215template <typename R, typename A1>
1216struct is_function_<R(A1)> {
1217 enum { value = 1 };
1218};
1219template <typename R, typename A1, typename A2>
1220struct is_function_<R(A1, A2)> {
1221 enum { value = 1 };
1222};
1223template <typename R, typename A1, typename A2, typename A3>
1224struct is_function_<R(A1, A2, A3)> {
1225 enum { value = 1 };
1226};
1227# endif // ZTH_TYPEDFIBER98
1228
1229# if __cplusplus >= 201103L
1230template <typename T, typename... Args>
1231struct is_function_<T(Args...)> {
1232 enum { value = 1 };
1233};
1234# endif // C++11
1235} // namespace impl
1236
1237template <typename T>
1241
1242template <typename T>
1244 typedef char yes;
1245 typedef long no;
1246
1247 template <typename C>
1248 static yes test(decltype(&C::operator())*);
1249
1250 template <typename>
1251 static no test(...);
1252
1253 enum { value = sizeof(test<T>(nullptr)) == sizeof(yes) };
1254};
1255
1256template <typename T>
1260
1261namespace impl {
1262
1263template <
1264 typename T, bool =
1265# if __cplusplus >= 201103L
1267# else
1269# endif // C++11
1270 >
1272 typedef typename fiber_type<T>::future type;
1273};
1274
1275template <typename T>
1276struct fiber_future_helper<T, false> {
1278};
1279
1280} // namespace impl
1281
1291template <typename T = void>
1292struct fiber_future : public impl::fiber_future_helper<T>::type {
1296
1297 template <typename F>
1298 // cppcheck-suppress noExplicitConstructor
1299 fiber_future(F& f) noexcept
1300 : base(static_cast<future_type const&>(f))
1301 {}
1302
1303 template <typename F>
1304 // cppcheck-suppress noExplicitConstructor
1305 fiber_future(F const& f) noexcept
1306 : base(static_cast<future_type const&>(f))
1307 {}
1308};
1309
1310# if __cplusplus >= 201703L
1311// Deduction guides for fiber_future.
1312template <typename F>
1314
1315template <typename F>
1317# endif // C++17
1318
1319
1320
1322// Simple join
1323//
1324
1325static inline void joinable(Fiber& f, Gate& g, Hook<Gate&>& UNUSED_PAR(join)) noexcept
1326{
1327 f << passOnExit(g);
1328}
1329
1330template <typename F>
1331static inline void
1332joinable(typename fiber_type<F>::fiber const& f, Gate& g, Hook<Gate&>& UNUSED_PAR(join)) noexcept
1333{
1334 f << passOnExit(g);
1335}
1336
1337template <typename T>
1338static inline void joinable(Future<T>& f, Gate& UNUSED_PAR(g), Hook<Gate&>& join) noexcept
1339{
1340 struct impl {
1341 static void cb(Gate& g_, void* f_) noexcept
1342 {
1343 Future<T>* f = static_cast<Future<T>*>(f_);
1344 f->wait();
1345 f->unused();
1346 g_.pass();
1347 }
1348 };
1349
1350 f.used();
1351 join.add(&impl::cb, static_cast<void*>(&f));
1352}
1353
1354template <typename T>
1355static inline void
1356joinable(SharedReference<Future<T> > const& f, Gate& g, Hook<Gate&>& join) noexcept
1357{
1358 joinable(f.get(), g, join);
1359}
1360
1375class joiner {
1377public:
1378 joiner() noexcept
1379 : m_gate(1)
1380 {}
1381
1382# if ZTH_TYPEDFIBER98
1383 template <typename J0>
1384 explicit joiner(J0& j0)
1385 : m_gate(2)
1386 {
1387 joinable(j0, m_gate, m_join);
1388 }
1389
1390 template <typename J0>
1391 explicit joiner(J0 const& j0)
1392 : m_gate(2)
1393 {
1394 joinable(j0, m_gate, m_join);
1395 }
1396
1397 template <typename J0, typename J1>
1398 explicit joiner(J0& j0, J1& j1)
1399 : m_gate(3)
1400 {
1401 joinable(j0, m_gate, m_join);
1402 joinable(j1, m_gate, m_join);
1403 }
1404
1405 template <typename J0, typename J1>
1406 explicit joiner(J0 const& j0, J1 const& j1)
1407 : m_gate(3)
1408 {
1409 joinable(j0, m_gate, m_join);
1410 joinable(j1, m_gate, m_join);
1411 }
1412
1413 template <typename J0, typename J1, typename J2>
1414 explicit joiner(J0& j0, J1& j1, J2& j2)
1415 : m_gate(4)
1416 {
1417 joinable(j0, m_gate, m_join);
1418 joinable(j1, m_gate, m_join);
1419 joinable(j2, m_gate, m_join);
1420 }
1421
1422 template <typename J0, typename J1, typename J2>
1423 explicit joiner(J0 const& j0, J1 const& j1, J2 const& j2)
1424 : m_gate(4)
1425 {
1426 joinable(j0, m_gate, m_join);
1427 joinable(j1, m_gate, m_join);
1428 joinable(j2, m_gate, m_join);
1429 }
1430
1431 template <typename J0, typename J1, typename J2, typename J3>
1432 explicit joiner(J0& j0, J1& j1, J2& j2, J3& j3)
1433 : m_gate(5)
1434 {
1435 joinable(j0, m_gate, m_join);
1436 joinable(j1, m_gate, m_join);
1437 joinable(j2, m_gate, m_join);
1438 joinable(j3, m_gate, m_join);
1439 }
1440
1441 template <typename J0, typename J1, typename J2, typename J3>
1442 explicit joiner(J0 const& j0, J1 const& j1, J2 const& j2, J3 const& j3)
1443 : m_gate(5)
1444 {
1445 joinable(j0, m_gate, m_join);
1446 joinable(j1, m_gate, m_join);
1447 joinable(j2, m_gate, m_join);
1448 joinable(j3, m_gate, m_join);
1449 }
1450
1451 template <typename J0, typename J1, typename J2, typename J3, typename J4>
1452 explicit joiner(J0& j0, J1& j1, J2& j2, J3& j3, J4& j4)
1453 : m_gate(6)
1454 {
1455 joinable(j0, m_gate, m_join);
1456 joinable(j1, m_gate, m_join);
1457 joinable(j2, m_gate, m_join);
1458 joinable(j3, m_gate, m_join);
1459 joinable(j4, m_gate, m_join);
1460 }
1461
1462 template <typename J0, typename J1, typename J2, typename J3, typename J4>
1463 explicit joiner(J0 const& j0, J1 const& j1, J2 const& j2, J3 const& j3, J4 const& j4)
1464 : m_gate(6)
1465 {
1466 joinable(j0, m_gate, m_join);
1467 joinable(j1, m_gate, m_join);
1468 joinable(j2, m_gate, m_join);
1469 joinable(j3, m_gate, m_join);
1470 joinable(j4, m_gate, m_join);
1471 }
1472# endif // ZTH_TYPEDFIBER98
1473
1474# if __cplusplus >= 201103L
1475 template <typename... J>
1476 explicit joiner(J&&... j)
1477 : m_gate{sizeof...(j) + 1U}
1478 {
1479 using dummy = int[];
1480 (void)dummy{0, (joinable(std::forward<J>(j), m_gate, m_join), 0)...};
1481 }
1482# endif // C++11
1483
1485 {
1486 m_join.once(m_gate);
1487 m_gate.wait();
1488 }
1489
1490private:
1491 Gate m_gate;
1492 Hook<Gate&> m_join;
1493};
1494
1495# if ZTH_TYPEDFIBER98
1496template <typename J0>
1497static inline void join(J0& j0)
1498{
1499 joiner jn(j0);
1500}
1501
1502template <typename J0, typename J1>
1503static inline void join(J0& j0, J1& j1)
1504{
1505 joiner jn(j0, j1);
1506}
1507
1508template <typename J0, typename J1, typename J2>
1509static inline void join(J0& j0, J1& j1, J2& j2)
1510{
1511 joiner jn(j0, j1, j2);
1512}
1513
1514template <typename J0, typename J1, typename J2, typename J3>
1515static inline void join(J0& j0, J1& j1, J2& j2, J3& j3)
1516{
1517 joiner jn(j0, j1, j2, j3);
1518}
1519
1520template <typename J0, typename J1, typename J2, typename J3, typename J4>
1521static inline void join(J0& j0, J1& j1, J2& j2, J3& j3, J4& j4)
1522{
1523 joiner jn(j0, j1, j2, j3, j4);
1524}
1525# endif
1526
1527# if __cplusplus >= 201103L
1532template <typename... J>
1533static inline void join(J&&... j)
1534{
1535 joiner jn{std::forward<J>(j)...};
1536}
1537# endif
1538
1539
1540
1542// zth_async macros
1543//
1544
1545namespace fibered {}
1546
1547} // namespace zth
1548
1549# define zth_fiber_declare_1(f) \
1550 namespace zth { \
1551 namespace fibered { \
1552 extern ::zth::fiber_type<decltype(&::f)>::factory const f; \
1553 } \
1554 }
1555
1560# define zth_fiber_declare(...) FOREACH(zth_fiber_declare_1, ##__VA_ARGS__)
1561
1562# define zth_fiber_define_1(storage, f) \
1563 namespace zth { \
1564 namespace fibered { \
1565 ZTH_DEPRECATED("Use zth::fiber(f, args...) instead") \
1566 storage ::zth::fiber_type<decltype(&::f)>::factory const \
1567 f(&::f, ::zth::Config::EnableDebugPrint || ::zth::Config::EnablePerfEvent \
1568 ? ZTH_STRINGIFY(f) "()" \
1569 : nullptr); /* NOLINT */ \
1570 } \
1571 } \
1572 typedef ::zth::fiber_type<decltype(&::f)>::future f##_future;
1573# define zth_fiber_define_extern_1(f) zth_fiber_define_1(extern, f)
1574# define zth_fiber_define_static_1(f) zth_fiber_define_1(static constexpr, f)
1575
1580# define zth_fiber_define(...) FOREACH(zth_fiber_define_extern_1, ##__VA_ARGS__)
1581
1586# define zth_fiber(...) FOREACH(zth_fiber_define_static_1, ##__VA_ARGS__)
1587
1607# define zth_async ::zth::fibered::
1608
1609
1610
1612// C API
1613//
1614
1619EXTERN_C ZTH_EXPORT ZTH_INLINE int zth_fiber_create(
1620 void (*f)(void*), void* arg = nullptr, size_t stack = 0,
1621 char const* name = nullptr) noexcept
1622{
1623 try {
1624 zth::factory(f, name)(arg) << zth::setStackSize(stack);
1625 } catch(std::bad_alloc const&) {
1626 return ENOMEM;
1627 } catch(zth::errno_exception const& e) {
1628# ifdef __cpp_exceptions
1629 return e.code;
1630# endif
1631 } catch(...) {
1632 return EAGAIN;
1633 }
1634
1635 return 0;
1636}
1637#else // !__cplusplus
1638
1639# include <stddef.h>
1640
1641ZTH_EXPORT int zth_fiber_create(void (*f)(void*), void* arg, size_t stack, char const* name);
1642
1643#endif // !__cplusplus
1644#endif // ZTH_ASYNC_H
#define REMOVE_FUNCTION_CVREF_SPECIALIZATIONS(P, suffix)
Definition async.h:673
#define REMOVE_FUNCTION_CVREF_MEMBER_SPECIALIZATIONS_CV(...)
Definition async.h:735
The fiber.
Definition fiber.h:49
State state() const noexcept
Definition fiber.h:140
Fiber-aware future.
Definition sync.h:1068
Fiber-aware barrier/gate.
Definition sync.h:1487
void wait()
Definition sync.h:1518
virtual char const * id_str() const noexcept override
Definition util.h:772
void setName(string const &name)
Definition util.h:751
string const & name() const noexcept
Definition util.h:746
SharedPointer_type::type type
Definition sync.h:200
constexpr T & get() const noexcept
Definition sync.h:163
TypedFiberType< Function >::fiberType TypedFiber_type
Definition async.h:962
TypedFiberType< Function >::returnType Return
Definition async.h:961
function_type_helper< F >::type Function
Definition async.h:960
fiber_type< Function > operator()(Args &&... args) const
Definition async.h:1006
SharedReference< typename TypedFiber_type::Future_type > Future
Definition async.h:963
constexpr TypedFiberFactory(F_ &&function, char const *name) noexcept
Definition async.h:972
constexpr TypedFiberFactory(Function function, char const *name) noexcept
Definition async.h:965
TypedFiber_type & polish(TypedFiber_type &fiber) const
Definition async.h:1013
Typed fiber class.
Definition async.h:55
virtual ~TypedFiber() noexcept override=default
void setFuture()
Definition async.h:139
SharedPointer< Future_type > const & withFuture()
Definition async.h:87
Future_type * future() const
Definition async.h:82
virtual void entry_()=0
Future< Return > Future_type
Definition async.h:59
constexpr TypedFiber()
Definition async.h:61
void setFuture(T const &r)
Definition async.h:133
void registerFuture(Future_type *future)
Definition async.h:67
static void entry(void *that)
Definition async.h:112
TypedFiberN(F_ &&func, Args_ &&... args)
Definition async.h:607
virtual ~TypedFiberN() final=default
Actual fiber implementation for arbitrary function types and arguments.
Definition async.h:566
virtual void entry_() final
Definition async.h:581
virtual ~TypedFiberN() final=default
TypedFiberN(F_ &&func, Args_ &&... args)
Definition async.h:573
void hatch(Fiber &fiber) noexcept
Definition worker.h:123
RAII class to join fibers and futures on destruction.
Definition async.h:1375
joiner(J &&... j)
Definition async.h:1476
joiner() noexcept
Definition async.h:1378
int zth_fiber_create(void(*f)(void *), void *arg=nullptr, size_t stack=0, char const *name=nullptr) noexcept
Run a function as a new fiber.
Definition async.h:1619
Worker & currentWorker() noexcept
Return the (thread-local) singleton Worker instance.
Definition worker.h:407
fiber_type< F >::factory factory(F &&f, char const *name=nullptr)
Create a new fiber.
Definition async.h:1131
fiber_type< F >::fiber fiber(F &&f, Args &&... args)
Create and start a new fiber.
Definition async.h:1192
#define zth_dbg(group, fmt, a...)
Debug printf()-like function.
Definition util.h:194
std::basic_string< char, std::char_traits< char >, Config::Allocator< char >::type > string
std::string type using Config::Allocator::type.
Definition util.h:315
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
Definition allocator.h:159
#define zth_throw(...)
Definition macros.h:365
#define is_default
Definition macros.h:212
#define LREF_QUALIFIED
Definition macros.h:215
#define ZTH_INLINE
Definition macros.h:129
#define UNUSED_PAR(name)
Definition macros.h:78
STL namespace.
::std::future< zth::type< T > > future
Definition future.h:40
string format(char const *fmt,...)
Format like sprintf(), but save the result in an zth::string.
Definition util.h:483
TypedFiber< R > & operator<<(TypedFiber< R > &fiber, setStackSize const &m)
Definition async.h:184
static bool const EnablePerfEvent
Enable (but not necessarily record) perf.
Definition config.h:174
static bool const EnableDebugPrint
Actually do print the debug output.
Definition config.h:97
static bool const EnableStackWaterMark
When true, enable stack watermark to detect maximum stack usage.
Definition config.h:144
static bool const NamedSynchronizer
Save names for all zth::Synchronizer instances.
Definition config.h:162
typename traitsType::return_type returnType
Definition async.h:825
Forces the fiber to have a future that outlives the fiber.
Definition async.h:310
Wrapper for an errno.
Definition exception.h:41
Base exception class for Zth exceptions.
Definition exception.h:16
Exception thrown when an operation cannot be performed, as the fiber is already dead.
Definition exception.h:26
The future returned by a fiber.
Definition async.h:1292
future_type::type return_type
Definition async.h:1295
fiber_future(F const &f) noexcept
Definition async.h:1305
impl::fiber_future_helper< T >::type future_type
Definition async.h:1293
fiber_future(F &f) noexcept
Definition async.h:1299
future_type base
Definition async.h:1294
fiber_type< function > fiber
Definition async.h:1038
SharedPointer< TypedFiber_type > _fiber
Definition async.h:1041
TypedFiberFactory< typename function_type_helper< F >::type > factory
Definition async.h:1035
future operator<<(asFuture const &)
Definition async.h:1100
fiber_type(TypedFiber_type &f) noexcept
Definition async.h:1044
TypedFiber_type::Return operator->()
Definition async.h:1055
factory::Function function
Definition async.h:1036
fiber const & operator<<(Manipulator const &m) const
Definition async.h:1085
factory::Future future
Definition async.h:1037
fiber & operator<<(Manipulator const &m) &
Definition async.h:1078
factory::TypedFiber_type TypedFiber_type
Definition async.h:1040
fiber && operator<<(Manipulator const &m) &&
Definition async.h:1093
TypedFiber_type::Return operator*()
Definition async.h:1048
std::tuple< Args... > args_type
Definition async.h:769
std::tuple< Args... > args_type
Definition async.h:792
std::tuple< Args... > args_type
Definition async.h:800
std::tuple< Args... > args_type
Definition async.h:809
std::tuple< Args... > args_type
Definition async.h:818
typename std::decay< F >::type functor_type
Definition async.h:775
typename functor_operator_type_::args_type args_type
Definition async.h:783
typename functor_operator_type_::return_type return_type
Definition async.h:782
static yes test(decltype(&C::operator()) *)
static no test(...)
SharedReference< Future< T > > type
Definition async.h:1277
fiber_type< T >::future type
Definition async.h:1272
Makes the fiber pass the given gate upon exit.
Definition async.h:266
static void atExit(Fiber &f, void *g) noexcept
Definition async.h:272
constexpr passOnExit(Gate &g) noexcept
Definition async.h:268
Gate & gate
Definition async.h:277
Change the name of a fiber returned by zth_async.
Definition async.h:201
setName(string const &n)
Definition async.h:207
string name
Definition async.h:224
setName(char const *n)
Definition async.h:203
setName(string &&n)
Definition async.h:210
Change the stack size of a fiber returned by zth_async.
Definition async.h:175
constexpr setStackSize(size_t s) noexcept
Definition async.h:178
#define ZTH_CLASS_NOCOPY(Class)
Definition util.h:234
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.
Definition util.h:60