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 <stdexcept>
30#include <type_traits>
31#include <utility>
32
33namespace ripple {
34
36class io_list final
37{
38public:
39 class work
40 {
41 template <class = void>
42 void
43 destroy();
44
45 friend class io_list;
46 io_list* ios_ = nullptr;
47
48 public:
49 virtual ~work()
50 {
51 destroy();
52 }
53
60 io_list&
62 {
63 return *ios_;
64 }
65
66 virtual void
67 close() = 0;
68 };
69
70private:
71 template <class = void>
72 void
73 destroy();
74
77 bool closed_ = false;
79 boost::container::flat_map<work*, std::weak_ptr<work>> map_;
80 std::function<void(void)> f_;
81
82public:
83 io_list() = default;
84
94 {
95 destroy();
96 }
97
104 bool
105 closed() const
106 {
107 return closed_;
108 }
109
128 template <class T, class... Args>
130 emplace(Args&&... args);
131
150 template <class Finisher>
151 void
152 close(Finisher&& f);
153
154 void
156 {
157 close([] {});
158 }
159
174 template <class = void>
175 void
176 join();
177};
178
179//------------------------------------------------------------------------------
180
181template <class>
182void
184{
185 if (!ios_)
186 return;
187 std::function<void(void)> f;
188 {
189 std::lock_guard lock(ios_->m_);
190 ios_->map_.erase(this);
191 if (--ios_->n_ == 0 && ios_->closed_)
192 {
193 std::swap(f, ios_->f_);
195 }
196 }
197 if (f)
198 f();
199}
200
201template <class>
202void
204{
205 close();
206 join();
207}
208
209template <class T, class... Args>
211io_list::emplace(Args&&... args)
212{
213 static_assert(
214 std::is_base_of<work, T>::value, "T must derive from io_list::work");
215 if (closed_)
216 return nullptr;
217 auto sp = std::make_shared<T>(std::forward<Args>(args)...);
218 decltype(sp) dead;
219
220 std::lock_guard lock(m_);
221 if (!closed_)
222 {
223 ++n_;
224 sp->work::ios_ = this;
225 map_.emplace(sp.get(), sp);
226 }
227 else
228 {
229 std::swap(sp, dead);
230 }
231 return sp;
232}
233
234template <class Finisher>
235void
236io_list::close(Finisher&& f)
237{
239 if (closed_)
240 return;
241 closed_ = true;
242 auto map = std::move(map_);
243 if (!map.empty())
244 {
245 f_ = std::forward<Finisher>(f);
246 lock.unlock();
247 for (auto const& p : map)
248 if (auto sp = p.second.lock())
249 sp->close();
250 }
251 else
252 {
253 lock.unlock();
254 f();
255 }
256}
257
258template <class>
259void
261{
263 cv_.wait(lock, [&] { return closed_ && n_ == 0; });
264}
265
266} // namespace ripple
267
268#endif
virtual void close()=0
io_list * ios_
Definition: io_list.h:46
virtual ~work()
Definition: io_list.h:49
io_list & ios()
Return the io_list associated with the work.
Definition: io_list.h:61
Manages a set of objects performing asynchronous I/O.
Definition: io_list.h:37
void destroy()
Definition: io_list.h:203
void close()
Definition: io_list.h:155
std::size_t n_
Definition: io_list.h:76
std::mutex m_
Definition: io_list.h:75
~io_list()
Destroy the list.
Definition: io_list.h:93
bool closed() const
Return true if the list is closed.
Definition: io_list.h:105
void join()
Block until the io_list stops.
Definition: io_list.h:260
boost::container::flat_map< work *, std::weak_ptr< work > > map_
Definition: io_list.h:79
std::shared_ptr< T > emplace(Args &&... args)
Create associated work if not closed.
Definition: io_list.h:211
std::function< void(void)> f_
Definition: io_list.h:80
std::condition_variable cv_
Definition: io_list.h:78
io_list()=default
bool closed_
Definition: io_list.h:77
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
T swap(T... args)