rippled
Loading...
Searching...
No Matches
io_list.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_SERVER_IO_LIST_H_INCLUDED
21#define RIPPLE_SERVER_IO_LIST_H_INCLUDED
22
23#include <boost/container/flat_map.hpp>
24
25#include <condition_variable>
26#include <functional>
27#include <memory>
28#include <mutex>
29#include <type_traits>
30#include <utility>
31
32namespace ripple {
33
35class io_list final
36{
37public:
38 class work
39 {
40 template <class = void>
41 void
42 destroy();
43
44 friend class io_list;
45 io_list* ios_ = nullptr;
46
47 public:
48 virtual ~work()
49 {
50 destroy();
51 }
52
59 io_list&
61 {
62 return *ios_;
63 }
64
65 virtual void
66 close() = 0;
67 };
68
69private:
70 template <class = void>
71 void
72 destroy();
73
76 bool closed_ = false;
78 boost::container::flat_map<work*, std::weak_ptr<work>> map_;
79 std::function<void(void)> f_;
80
81public:
82 io_list() = default;
83
93 {
94 destroy();
95 }
96
103 bool
104 closed() const
105 {
106 return closed_;
107 }
108
127 template <class T, class... Args>
129 emplace(Args&&... args);
130
149 template <class Finisher>
150 void
151 close(Finisher&& f);
152
153 void
155 {
156 close([] {});
157 }
158
173 template <class = void>
174 void
175 join();
176};
177
178//------------------------------------------------------------------------------
179
180template <class>
181void
183{
184 if (!ios_)
185 return;
186 std::function<void(void)> f;
187 {
188 std::lock_guard lock(ios_->m_);
189 ios_->map_.erase(this);
190 if (--ios_->n_ == 0 && ios_->closed_)
191 {
192 std::swap(f, ios_->f_);
194 }
195 }
196 if (f)
197 f();
198}
199
200template <class>
201void
203{
204 close();
205 join();
206}
207
208template <class T, class... Args>
210io_list::emplace(Args&&... args)
211{
212 static_assert(
213 std::is_base_of<work, T>::value, "T must derive from io_list::work");
214 if (closed_)
215 return nullptr;
216 auto sp = std::make_shared<T>(std::forward<Args>(args)...);
217 decltype(sp) dead;
218
219 std::lock_guard lock(m_);
220 if (!closed_)
221 {
222 ++n_;
223 sp->work::ios_ = this;
224 map_.emplace(sp.get(), sp);
225 }
226 else
227 {
228 std::swap(sp, dead);
229 }
230 return sp;
231}
232
233template <class Finisher>
234void
235io_list::close(Finisher&& f)
236{
238 if (closed_)
239 return;
240 closed_ = true;
241 auto map = std::move(map_);
242 if (!map.empty())
243 {
245 lock.unlock();
246 for (auto const& p : map)
247 if (auto sp = p.second.lock())
248 sp->close();
249 }
250 else
251 {
252 lock.unlock();
253 f();
254 }
255}
256
257template <class>
258void
260{
262 cv_.wait(lock, [&] { return closed_ && n_ == 0; });
263}
264
265} // namespace ripple
266
267#endif
virtual void close()=0
io_list & ios()
Return the io_list associated with the work.
Definition io_list.h:60
Manages a set of objects performing asynchronous I/O.
Definition io_list.h:36
void destroy()
Definition io_list.h:202
std::size_t n_
Definition io_list.h:75
std::mutex m_
Definition io_list.h:74
~io_list()
Destroy the list.
Definition io_list.h:92
bool closed() const
Return true if the list is closed.
Definition io_list.h:104
void join()
Block until the io_list stops.
Definition io_list.h:259
boost::container::flat_map< work *, std::weak_ptr< work > > map_
Definition io_list.h:78
std::shared_ptr< T > emplace(Args &&... args)
Create associated work if not closed.
Definition io_list.h:210
std::function< void(void)> f_
Definition io_list.h:79
std::condition_variable cv_
Definition io_list.h:77
io_list()=default
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
T swap(T... args)