]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/include/seastar/core/std-coroutine.hh
buildsys: change download over to reef release
[ceph.git] / ceph / src / seastar / include / seastar / core / std-coroutine.hh
CommitLineData
9f95a23c
TL
1/*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18/*
19 * Copyright (C) 2019 ScyllaDB Ltd.
20 */
21
22#pragma once
23
f67539c2
TL
24// Clang currently only supports the TS
25#if __has_include(<coroutine>) && !defined(__clang__)
26#include <coroutine>
27#define SEASTAR_INTERNAL_COROUTINE_NAMESPACE std
28#elif __has_include(<experimental/coroutine>)
9f95a23c 29#include <experimental/coroutine>
f67539c2 30#define SEASTAR_INTERNAL_COROUTINE_NAMESPACE std::experimental
9f95a23c 31#else
f67539c2 32#define SEASTAR_INTERNAL_COROUTINE_NAMESPACE std::experimental
9f95a23c
TL
33
34// We are not exactly allowed to defined anything in the std namespace, but this
35// makes coroutines work with libstdc++. All of this is experimental anyway.
36
37namespace std::experimental {
38
20effc67 39template<typename Promise = void>
9f95a23c
TL
40class coroutine_handle {
41 void* _pointer = nullptr;
42public:
43 coroutine_handle() = default;
44
45 coroutine_handle &operator=(nullptr_t) noexcept {
46 _pointer = nullptr;
47 return *this;
48 }
49
50 explicit operator bool() const noexcept { return _pointer; }
51
52 static coroutine_handle from_address(void* ptr) noexcept {
53 coroutine_handle hndl;
54 hndl._pointer =ptr;
55 return hndl;
56 }
57 void* address() const noexcept { return _pointer; }
58
59 static coroutine_handle from_promise(Promise& promise) noexcept {
60 coroutine_handle hndl;
61 hndl._pointer = __builtin_coro_promise(&promise, alignof(Promise), true);
62 return hndl;
63 }
64 Promise& promise() const noexcept {
65 return *reinterpret_cast<Promise*>(__builtin_coro_promise(_pointer, alignof(Promise), false));
66 }
67
68 void operator()() noexcept { resume(); }
69
70 void resume() const noexcept { __builtin_coro_resume(_pointer); }
71 void destroy() const noexcept { __builtin_coro_destroy(_pointer); }
72 bool done() const noexcept { return __builtin_coro_done(_pointer); }
20effc67
TL
73
74 operator coroutine_handle<>() const noexcept;
75};
76
77template<>
78class coroutine_handle<void> {
79 void* _pointer = nullptr;
80public:
81 coroutine_handle() = default;
82
83 coroutine_handle &operator=(nullptr_t) noexcept {
84 _pointer = nullptr;
85 return *this;
86 }
87
88 explicit operator bool() const noexcept { return _pointer; }
89
90 static coroutine_handle from_address(void* ptr) noexcept {
91 coroutine_handle hndl;
92 hndl._pointer = ptr;
93 return hndl;
94 }
95 void* address() const noexcept { return _pointer; }
96
97 void operator()() noexcept { resume(); }
98
99 void resume() const noexcept { __builtin_coro_resume(_pointer); }
100 void destroy() const noexcept { __builtin_coro_destroy(_pointer); }
101 bool done() const noexcept { return __builtin_coro_done(_pointer); }
9f95a23c
TL
102};
103
104struct suspend_never {
105 constexpr bool await_ready() const noexcept { return true; }
106 template<typename T>
107 constexpr void await_suspend(coroutine_handle<T>) noexcept { }
108 constexpr void await_resume() noexcept { }
109};
110
111struct suspend_always {
112 constexpr bool await_ready() const noexcept { return false; }
113 template<typename T>
114 constexpr void await_suspend(coroutine_handle<T>) noexcept { }
115 constexpr void await_resume() noexcept { }
116};
117
20effc67
TL
118template <typename Promise>
119coroutine_handle<Promise>::operator coroutine_handle<>() const noexcept {
120 return coroutine_handle<>::from_address(address());
121}
122
9f95a23c
TL
123template<typename T, typename... Args>
124class coroutine_traits { };
125
126}
127
128#endif