rippled
Loading...
Searching...
No Matches
Checker.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_PEERFINDER_CHECKER_H_INCLUDED
21#define RIPPLE_PEERFINDER_CHECKER_H_INCLUDED
22
23#include <xrpl/beast/net/IPAddressConversion.h>
24#include <boost/asio/detail/handler_invoke_helpers.hpp>
25#include <boost/asio/io_service.hpp>
26#include <boost/asio/ip/tcp.hpp>
27#include <boost/intrusive/list.hpp>
28#include <boost/system/error_code.hpp>
29#include <condition_variable>
30#include <memory>
31#include <mutex>
32#include <utility>
33
34namespace ripple {
35namespace PeerFinder {
36
38template <class Protocol = boost::asio::ip::tcp>
40{
41private:
42 using error_code = boost::system::error_code;
43
45 : boost::intrusive::list_base_hook<
46 boost::intrusive::link_mode<boost::intrusive::normal_link>>
47 {
48 virtual ~basic_async_op() = default;
49
50 virtual void
51 stop() = 0;
52
53 virtual void
54 operator()(error_code const& ec) = 0;
55 };
56
57 template <class Handler>
59 {
60 using socket_type = typename Protocol::socket;
61 using endpoint_type = typename Protocol::endpoint;
62
65 Handler handler_;
66
67 async_op(
68 Checker& owner,
69 boost::asio::io_service& io_service,
70 Handler&& handler);
71
73
74 void
75 stop() override;
76
77 void
78 operator()(error_code const& ec) override;
79 };
80
81 //--------------------------------------------------------------------------
82
83 using list_type = typename boost::intrusive::make_list<
85 boost::intrusive::constant_time_size<true>>::type;
86
89 boost::asio::io_service& io_service_;
91 bool stop_ = false;
92
93public:
94 explicit Checker(boost::asio::io_service& io_service);
95
103
110 void
112
114 void
116
121 template <class Handler>
122 void
123 async_connect(beast::IP::Endpoint const& endpoint, Handler&& handler);
124
125private:
126 void
127 remove(basic_async_op& op);
128};
129
130//------------------------------------------------------------------------------
131
132template <class Protocol>
133template <class Handler>
135 Checker& owner,
136 boost::asio::io_service& io_service,
137 Handler&& handler)
138 : checker_(owner)
139 , socket_(io_service)
140 , handler_(std::forward<Handler>(handler))
141{
142}
143
144template <class Protocol>
145template <class Handler>
147{
148 checker_.remove(*this);
149}
150
151template <class Protocol>
152template <class Handler>
153void
155{
156 error_code ec;
157 socket_.cancel(ec);
158}
159
160template <class Protocol>
161template <class Handler>
162void
164{
165 handler_(ec);
166}
167
168//------------------------------------------------------------------------------
169
170template <class Protocol>
171Checker<Protocol>::Checker(boost::asio::io_service& io_service)
172 : io_service_(io_service)
173{
174}
175
176template <class Protocol>
178{
179 wait();
180}
181
182template <class Protocol>
183void
185{
186 std::lock_guard lock(mutex_);
187 if (!stop_)
188 {
189 stop_ = true;
190 for (auto& c : list_)
191 c.stop();
192 }
193}
194
195template <class Protocol>
196void
198{
199 std::unique_lock<std::mutex> lock(mutex_);
200 while (!list_.empty())
201 cond_.wait(lock);
202}
203
204template <class Protocol>
205template <class Handler>
206void
208 beast::IP::Endpoint const& endpoint,
209 Handler&& handler)
210{
211 auto const op = std::make_shared<async_op<Handler>>(
212 *this, io_service_, std::forward<Handler>(handler));
213 {
214 std::lock_guard lock(mutex_);
215 list_.push_back(*op);
216 }
217 op->socket_.async_connect(
219 std::bind(&basic_async_op::operator(), op, std::placeholders::_1));
220}
221
222template <class Protocol>
223void
225{
226 std::lock_guard lock(mutex_);
227 list_.erase(list_.iterator_to(op));
228 if (list_.size() == 0)
229 cond_.notify_all();
230}
231
232} // namespace PeerFinder
233} // namespace ripple
234
235#endif
T bind(T... args)
A version-independent IP address and port combination.
Definition: IPEndpoint.h:39
Tests remote listening sockets to make sure they are connectible.
Definition: Checker.h:40
boost::system::error_code error_code
Definition: Checker.h:42
void remove(basic_async_op &op)
Definition: Checker.h:224
std::condition_variable cond_
Definition: Checker.h:88
void stop()
Stop the service.
Definition: Checker.h:184
boost::asio::io_service & io_service_
Definition: Checker.h:89
Checker(boost::asio::io_service &io_service)
Definition: Checker.h:171
~Checker()
Destroy the service.
Definition: Checker.h:177
void async_connect(beast::IP::Endpoint const &endpoint, Handler &&handler)
Performs an async connection test on the specified endpoint.
Definition: Checker.h:207
typename boost::intrusive::make_list< basic_async_op, boost::intrusive::constant_time_size< true > >::type list_type
Definition: Checker.h:85
void wait()
Block until all pending I/O completes.
Definition: Checker.h:197
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
STL namespace.
static boost::asio::ip::tcp::endpoint to_asio_endpoint(IP::Endpoint const &address)
void operator()(error_code const &ec) override
Definition: Checker.h:163
typename Protocol::endpoint endpoint_type
Definition: Checker.h:61
typename Protocol::socket socket_type
Definition: Checker.h:60
virtual void operator()(error_code const &ec)=0