MPD: lib/nfs/Cancellable.hxx Source File

MPD 0.20.15

Cancellable.hxx
Go to the documentation of this file.
1 /*
2 * Copyright 2003-2017 The Music Player Daemon Project
3 * http://www.musicpd.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef MPD_NFS_CANCELLABLE_HXX
21 #define MPD_NFS_CANCELLABLE_HXX
22
23 #include "Compiler.h"
24
25 #include <boost/intrusive/list.hpp>
26
27 #include <algorithm>
28
29 #include <assert.h>
30
31 template<typename T>
32 class CancellablePointer
33 : public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
34 public:
35 typedef T *pointer_type;
36 typedef T &reference_type;
37 typedef const T &const_reference_type;
38
39 private:
40 pointer_type p;
41
42 public:
43 explicit CancellablePointer(reference_type _p):p(&_p) {}
44
45 CancellablePointer(const CancellablePointer &) = delete;
46
47 constexpr bool IsCancelled() const {
48 return p == nullptr;
49 }
50
51 void Cancel() {
52 assert(!IsCancelled());
53
54 p = nullptr;
55 }
56
57 reference_type Get() {
58 assert(p != nullptr);
59
60 return *p;
61 }
62
63 constexpr bool Is(const_reference_type other) const {
64 return p == &other;
65 }
66 };
67
68 template<typename T, typename CT=CancellablePointer<T>>
69 class CancellableList {
70 public:
71 typedef typename CT::reference_type reference_type;
72 typedef typename CT::const_reference_type const_reference_type;
73
74 private:
75 typedef boost::intrusive::list<CT,
76 boost::intrusive::constant_time_size<false>> List;
77 typedef typename List::iterator iterator;
78 typedef typename List::const_iterator const_iterator;
79 List list;
80
81 class MatchPointer {
82 const_reference_type p;
83
84 public:
85 explicit constexpr MatchPointer(const_reference_type _p)
86 :p(_p) {}
87
88 constexpr bool operator()(const CT &a) const {
89 return a.Is(p);
90 }
91 };
92
93 gcc_pure
94 iterator Find(reference_type p) noexcept {
95 return std::find_if(list.begin(), list.end(), MatchPointer(p));
96 }
97
98 gcc_pure
99 const_iterator Find(const_reference_type p) const noexcept {
100 return std::find_if(list.begin(), list.end(), MatchPointer(p));
101 }
102
103 gcc_pure
104 iterator Find(CT &c) noexcept {
105 return list.iterator_to(c);
106 }
107
108 gcc_pure
109 const_iterator Find(const CT &c) const noexcept {
110 return list.iterator_to(c);
111 }
112
113 public:
114 #ifndef NDEBUG
115 gcc_pure
116 bool IsEmpty() const noexcept {
117 for (const auto &c : list)
118 if (!c.IsCancelled())
119 return false;
120
121 return true;
122 }
123 #endif
124
125 gcc_pure
126 bool Contains(const_reference_type p) const noexcept {
127 return Find(p) != list.end();
128 }
129
130 template<typename... Args>
131 CT &Add(reference_type p, Args&&... args) {
132 assert(Find(p) == list.end());
133
134 CT *c = new CT(p, std::forward<Args>(args)...);
135 list.push_back(*c);
136 return *c;
137 }
138
139 void Remove(CT &ct) {
140 auto i = Find(ct);
141 assert(i != list.end());
142
143 list.erase(i);
144 delete &ct;
145 }
146
147 void Cancel(reference_type p) {
148 auto i = Find(p);
149 assert(i != list.end());
150
151 i->Cancel();
152 }
153
154 CT &Get(reference_type p) noexcept {
155 auto i = Find(p);
156 assert(i != list.end());
157
158 return *i;
159 }
160
161 template<typename F>
162 void ForEach(F &&f) {
163 for (CT &i : list)
164 f(i);
165 }
166 };
167
168 #endif
CancellablePointer::const_reference_type
const T & const_reference_type
Definition: Cancellable.hxx:37
CancellablePointer::reference_type
T & reference_type
Definition: Cancellable.hxx:36
CancellableList::ForEach
void ForEach(F &&f)
Definition: Cancellable.hxx:162
CancellableList::Contains
gcc_pure bool Contains(const_reference_type p) const noexcept
Definition: Cancellable.hxx:126
CancellableList
Definition: Cancellable.hxx:69
CancellablePointer
Definition: Cancellable.hxx:32
CancellableList::Add
CT & Add(reference_type p, Args &&... args)
Definition: Cancellable.hxx:131
CancellablePointer::Get
reference_type Get()
Definition: Cancellable.hxx:57
CancellableList::reference_type
CT::reference_type reference_type
Definition: Cancellable.hxx:71
Compiler.h
CancellablePointer::pointer_type
T * pointer_type
Definition: Cancellable.hxx:35
CancellableList::Cancel
void Cancel(reference_type p)
Definition: Cancellable.hxx:147
CancellablePointer::CancellablePointer
CancellablePointer(reference_type _p)
Definition: Cancellable.hxx:43
NfsCallback
Callbacks for an asynchronous libnfs operation.
Definition: Callback.hxx:32
CancellablePointer::Cancel
void Cancel()
Definition: Cancellable.hxx:51
CancellablePointer::IsCancelled
constexpr bool IsCancelled() const
Definition: Cancellable.hxx:47
CancellablePointer::Is
constexpr bool Is(const_reference_type other) const
Definition: Cancellable.hxx:63
CancellableList::IsEmpty
gcc_pure bool IsEmpty() const noexcept
Definition: Cancellable.hxx:116
gcc_pure
#define gcc_pure
Definition: Compiler.h:116
CancellableList::Remove
void Remove(CT &ct)
Definition: Cancellable.hxx:139
CancellableList::Get
CT & Get(reference_type p) noexcept
Definition: Cancellable.hxx:154
CancellableList::const_reference_type
CT::const_reference_type const_reference_type
Definition: Cancellable.hxx:72