Seastar
High performance C++ framework for concurrent servers
closeable.hh
Go to the documentation of this file.
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) 2021 Cloudius Systems, Ltd.
20  */
21 
22 #pragma once
23 
24 #include <functional>
25 #include <seastar/core/future.hh>
26 #include <seastar/util/concepts.hh>
27 #include <seastar/util/defer.hh>
28 
30 
32 
33 namespace seastar {
34 
35 SEASTAR_CONCEPT(
36 template <typename Object>
37 concept closeable = requires (Object o) {
38  { o.close() } SEASTAR_DEFERRED_ACTION_NOEXCEPT -> std::same_as<future<>>;
39 };
40 )
41 
49 template <typename Object>
50 SEASTAR_CONCEPT( requires closeable<Object> )
51 class [[nodiscard]] deferred_close {
52  std::reference_wrapper<Object> _obj;
53  bool _closed = false;
54 
55  void do_close() noexcept {
56  if (!_closed) {
57  _closed = true;
58  _obj.get().close().get();
59  }
60  }
61 public:
64  deferred_close(Object& obj) noexcept : _obj(obj) {}
67  deferred_close(deferred_close&& x) noexcept : _obj(x._obj), _closed(std::exchange(x._closed, true)) {}
68  deferred_close(const deferred_close&) = delete;
73  do_close();
74  _obj = x._obj;
75  _closed = std::exchange(x._closed, true);
76  return *this;
77  }
80  do_close();
81  }
83  void close_now() noexcept {
84  assert(!_closed);
85  do_close();
86  }
87 
90  void cancel() noexcept {
91  _closed = true;
92  }
93 };
94 
95 template <typename Closeable, typename Func>
96 SEASTAR_CONCEPT(
97 requires closeable<Closeable> && std::invocable<Func, Closeable&> &&
98  std::is_nothrow_move_constructible_v<Closeable> && std::is_nothrow_move_constructible_v<Func>
99 )
100 inline futurize_t<std::invoke_result_t<Func, Closeable&>>
101 with_closeable(Closeable&& obj, Func func) noexcept {
102  return do_with(std::move(obj), [func = std::move(func)] (Closeable& obj) mutable {
103  return futurize_invoke(func, obj).finally([&obj] {
104  return obj.close();
105  });
106  });
107 }
108 
109 SEASTAR_CONCEPT(
110 template <typename Object>
111 concept stoppable = requires (Object o) {
112  { o.stop() } SEASTAR_DEFERRED_ACTION_NOEXCEPT -> std::same_as<future<>>;
113 };
114 )
115 
123 template <typename Object>
124 SEASTAR_CONCEPT( requires stoppable<Object> )
125 class [[nodiscard]] deferred_stop {
126  std::reference_wrapper<Object> _obj;
127  bool _stopped = false;
128 
129  void do_stop() noexcept {
130  if (!_stopped) {
131  _stopped = true;
132  _obj.get().stop().get();
133  }
134  }
135 public:
138  deferred_stop(Object& obj) noexcept : _obj(obj) {}
141  deferred_stop(deferred_stop&& x) noexcept : _obj(x._obj), _stopped(std::exchange(x._stopped, true)) {}
142  deferred_stop(const deferred_stop&) = delete;
147  do_stop();
148  _obj = x._obj;
149  _stopped = std::exchange(x._stopped, true);
150  return *this;
151  }
154  do_stop();
155  }
157  void stop_now() noexcept {
158  assert(!_stopped);
159  do_stop();
160  }
161 
164  void cancel() noexcept {
165  _stopped = true;
166  }
167 };
168 
169 template <typename Stoppable, typename Func>
170 SEASTAR_CONCEPT(
171 requires stoppable<Stoppable> && std::invocable<Func, Stoppable&> &&
172  std::is_nothrow_move_constructible_v<Stoppable> && std::is_nothrow_move_constructible_v<Func>
173 )
174 inline futurize_t<std::invoke_result_t<Func, Stoppable&>>
175 with_stoppable(Stoppable&& obj, Func func) noexcept {
176  return do_with(std::move(obj), [func = std::move(func)] (Stoppable& obj) mutable {
177  return futurize_invoke(func, obj).finally([&obj] {
178  return obj.stop();
179  });
180  });
181 }
182 
183 } // namespace seastar
Definition: closeable.hh:51
void close_now() noexcept
Close obj once now.
Definition: closeable.hh:83
void cancel() noexcept
Definition: closeable.hh:90
deferred_close & operator=(deferred_close &&x) noexcept
Definition: closeable.hh:72
deferred_close(deferred_close &&x) noexcept
Definition: closeable.hh:67
~deferred_close()
Destruct the deferred_close object and auto-close obj.
Definition: closeable.hh:79
deferred_close(Object &obj) noexcept
Definition: closeable.hh:64
Definition: closeable.hh:125
deferred_stop(Object &obj) noexcept
Definition: closeable.hh:138
void stop_now() noexcept
Stop obj once now.
Definition: closeable.hh:157
deferred_stop(deferred_stop &&x) noexcept
Definition: closeable.hh:141
deferred_stop & operator=(deferred_stop &&x) noexcept
Definition: closeable.hh:146
~deferred_stop()
Destruct the deferred_stop object and auto-stop obj.
Definition: closeable.hh:153
void cancel() noexcept
Definition: closeable.hh:164
auto do_with(T1 &&rv1, T2 &&rv2, More &&... more) noexcept
Definition: do_with.hh:135
Seastar API namespace.
Definition: abort_on_ebadf.hh:26