Seastar
High performance C++ framework for concurrent servers
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
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 <concepts>
25#include <functional>
26#include <seastar/core/future.hh>
27#include <seastar/util/assert.hh>
28#include <seastar/util/defer.hh>
29
31
33
34namespace seastar {
35
36template <typename Object>
37concept closeable = requires (Object o) {
38 { o.close() } SEASTAR_DEFERRED_ACTION_NOEXCEPT -> std::same_as<future<>>;
39};
40
48template <typename Object>
49requires closeable<Object>
50class [[nodiscard]] deferred_close {
51 std::reference_wrapper<Object> _obj;
52 bool _closed = false;
53
54 void do_close() noexcept {
55 if (!_closed) {
56 _closed = true;
57 _obj.get().close().get();
58 }
59 }
60public:
63 deferred_close(Object& obj) noexcept : _obj(obj) {}
66 deferred_close(deferred_close&& x) noexcept : _obj(x._obj), _closed(std::exchange(x._closed, true)) {}
67 deferred_close(const deferred_close&) = delete;
72 do_close();
73 _obj = x._obj;
74 _closed = std::exchange(x._closed, true);
75 return *this;
76 }
79 do_close();
80 }
82 void close_now() noexcept {
83 SEASTAR_ASSERT(!_closed);
84 do_close();
85 }
86
89 void cancel() noexcept {
90 _closed = true;
91 }
92};
93
94template <closeable Closeable, std::invocable<Closeable&> Func>
95requires std::is_nothrow_move_constructible_v<Closeable> && std::is_nothrow_move_constructible_v<Func>
96inline futurize_t<std::invoke_result_t<Func, Closeable&>>
97with_closeable(Closeable&& obj, Func func) noexcept {
98 return do_with(std::move(obj), [func = std::move(func)] (Closeable& obj) mutable {
99 return futurize_invoke(func, obj).finally([&obj] {
100 return obj.close();
101 });
102 });
103}
104
105template <typename Object>
106concept stoppable = requires (Object o) {
107 { o.stop() } SEASTAR_DEFERRED_ACTION_NOEXCEPT -> std::same_as<future<>>;
108};
109
117template <typename Object>
118requires stoppable<Object>
119class [[nodiscard]] deferred_stop {
120 std::reference_wrapper<Object> _obj;
121 bool _stopped = false;
122
123 void do_stop() noexcept {
124 if (!_stopped) {
125 _stopped = true;
126 _obj.get().stop().get();
127 }
128 }
129public:
132 deferred_stop(Object& obj) noexcept : _obj(obj) {}
135 deferred_stop(deferred_stop&& x) noexcept : _obj(x._obj), _stopped(std::exchange(x._stopped, true)) {}
136 deferred_stop(const deferred_stop&) = delete;
141 do_stop();
142 _obj = x._obj;
143 _stopped = std::exchange(x._stopped, true);
144 return *this;
145 }
148 do_stop();
149 }
151 void stop_now() noexcept {
152 SEASTAR_ASSERT(!_stopped);
153 do_stop();
154 }
155
158 void cancel() noexcept {
159 _stopped = true;
160 }
161};
162
163template <stoppable Stoppable, std::invocable<Stoppable&> Func>
164requires std::is_nothrow_move_constructible_v<Stoppable> && std::is_nothrow_move_constructible_v<Func>
165inline futurize_t<std::invoke_result_t<Func, Stoppable&>>
166with_stoppable(Stoppable&& obj, Func func) noexcept {
167 return do_with(std::move(obj), [func = std::move(func)] (Stoppable& obj) mutable {
168 return futurize_invoke(func, obj).finally([&obj] {
169 return obj.stop();
170 });
171 });
172}
173
174} // namespace seastar
Definition: closeable.hh:50
void close_now() noexcept
Close obj once now.
Definition: closeable.hh:82
deferred_close & operator=(deferred_close &&x) noexcept
Definition: closeable.hh:71
void cancel() noexcept
Definition: closeable.hh:89
deferred_close(deferred_close &&x) noexcept
Definition: closeable.hh:66
~deferred_close()
Destruct the deferred_close object and auto-close obj.
Definition: closeable.hh:78
deferred_close(Object &obj) noexcept
Definition: closeable.hh:63
Definition: closeable.hh:119
deferred_stop(Object &obj) noexcept
Definition: closeable.hh:132
void stop_now() noexcept
Stop obj once now.
Definition: closeable.hh:151
deferred_stop(deferred_stop &&x) noexcept
Definition: closeable.hh:135
~deferred_stop()
Destruct the deferred_stop object and auto-stop obj.
Definition: closeable.hh:147
void cancel() noexcept
Definition: closeable.hh:158
deferred_stop & operator=(deferred_stop &&x) noexcept
Definition: closeable.hh:140
auto do_with(T1 &&rv1, T2 &&rv2, More &&... more) noexcept
Definition: do_with.hh:135
Seastar API namespace.
Definition: abort_on_ebadf.hh:26