]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/example/cpp03/allocation/server.cpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / libs / asio / example / cpp03 / allocation / server.cpp
CommitLineData
7c673cae
FG
1//
2// server.cpp
3// ~~~~~~~~~~
4//
1e59de90 5// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#include <cstdlib>
12#include <iostream>
13#include <boost/aligned_storage.hpp>
14#include <boost/array.hpp>
f67539c2 15#include <boost/bind/bind.hpp>
7c673cae
FG
16#include <boost/enable_shared_from_this.hpp>
17#include <boost/noncopyable.hpp>
18#include <boost/shared_ptr.hpp>
19#include <boost/asio.hpp>
20
21using boost::asio::ip::tcp;
22
23// Class to manage the memory to be used for handler-based custom allocation.
24// It contains a single block of memory which may be returned for allocation
25// requests. If the memory is in use when an allocation request is made, the
26// allocator delegates allocation to the global heap.
b32b8144 27class handler_memory
7c673cae
FG
28 : private boost::noncopyable
29{
30public:
b32b8144 31 handler_memory()
7c673cae
FG
32 : in_use_(false)
33 {
34 }
35
36 void* allocate(std::size_t size)
37 {
38 if (!in_use_ && size < storage_.size)
39 {
40 in_use_ = true;
41 return storage_.address();
42 }
43 else
44 {
45 return ::operator new(size);
46 }
47 }
48
49 void deallocate(void* pointer)
50 {
51 if (pointer == storage_.address())
52 {
53 in_use_ = false;
54 }
55 else
56 {
57 ::operator delete(pointer);
58 }
59 }
60
61private:
62 // Storage space used for handler-based custom memory allocation.
63 boost::aligned_storage<1024> storage_;
64
65 // Whether the handler-based custom allocation storage has been used.
66 bool in_use_;
67};
68
b32b8144
FG
69// The allocator to be associated with the handler objects. This allocator only
70// needs to satisfy the C++11 minimal allocator requirements, plus rebind when
71// targeting C++03.
72template <typename T>
73class handler_allocator
74{
75public:
76 typedef T value_type;
77
78 explicit handler_allocator(handler_memory& mem)
79 : memory_(mem)
80 {
81 }
82
83 template <typename U>
84 handler_allocator(const handler_allocator<U>& other)
85 : memory_(other.memory_)
86 {
87 }
88
89 template <typename U>
90 struct rebind
91 {
92 typedef handler_allocator<U> other;
93 };
94
95 bool operator==(const handler_allocator& other) const
96 {
97 return &memory_ == &other.memory_;
98 }
99
100 bool operator!=(const handler_allocator& other) const
101 {
102 return &memory_ != &other.memory_;
103 }
104
105 T* allocate(std::size_t n) const
106 {
107 return static_cast<T*>(memory_.allocate(sizeof(T) * n));
108 }
109
110 void deallocate(T* p, std::size_t /*n*/) const
111 {
112 return memory_.deallocate(p);
113 }
114
115//private:
116 // The underlying memory.
117 handler_memory& memory_;
118};
119
7c673cae
FG
120class session
121 : public boost::enable_shared_from_this<session>
122{
123public:
b32b8144
FG
124 session(boost::asio::io_context& io_context)
125 : socket_(io_context)
7c673cae
FG
126 {
127 }
128
129 tcp::socket& socket()
130 {
131 return socket_;
132 }
133
134 void start()
135 {
136 socket_.async_read_some(boost::asio::buffer(data_),
1e59de90
TL
137 boost::asio::bind_allocator(
138 handler_allocator<int>(handler_memory_),
7c673cae
FG
139 boost::bind(&session::handle_read,
140 shared_from_this(),
141 boost::asio::placeholders::error,
142 boost::asio::placeholders::bytes_transferred)));
143 }
144
145 void handle_read(const boost::system::error_code& error,
146 size_t bytes_transferred)
147 {
148 if (!error)
149 {
150 boost::asio::async_write(socket_,
151 boost::asio::buffer(data_, bytes_transferred),
1e59de90
TL
152 boost::asio::bind_allocator(
153 handler_allocator<int>(handler_memory_),
7c673cae
FG
154 boost::bind(&session::handle_write,
155 shared_from_this(),
156 boost::asio::placeholders::error)));
157 }
158 }
159
160 void handle_write(const boost::system::error_code& error)
161 {
162 if (!error)
163 {
164 socket_.async_read_some(boost::asio::buffer(data_),
1e59de90
TL
165 boost::asio::bind_allocator(
166 handler_allocator<int>(handler_memory_),
7c673cae
FG
167 boost::bind(&session::handle_read,
168 shared_from_this(),
169 boost::asio::placeholders::error,
170 boost::asio::placeholders::bytes_transferred)));
171 }
172 }
173
174private:
175 // The socket used to communicate with the client.
176 tcp::socket socket_;
177
178 // Buffer used to store data received from the client.
179 boost::array<char, 1024> data_;
180
b32b8144
FG
181 // The memory to use for handler-based custom memory allocation.
182 handler_memory handler_memory_;
7c673cae
FG
183};
184
185typedef boost::shared_ptr<session> session_ptr;
186
187class server
188{
189public:
b32b8144
FG
190 server(boost::asio::io_context& io_context, short port)
191 : io_context_(io_context),
192 acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
7c673cae 193 {
b32b8144 194 session_ptr new_session(new session(io_context_));
7c673cae
FG
195 acceptor_.async_accept(new_session->socket(),
196 boost::bind(&server::handle_accept, this, new_session,
197 boost::asio::placeholders::error));
198 }
199
200 void handle_accept(session_ptr new_session,
201 const boost::system::error_code& error)
202 {
203 if (!error)
204 {
205 new_session->start();
206 }
207
b32b8144 208 new_session.reset(new session(io_context_));
7c673cae
FG
209 acceptor_.async_accept(new_session->socket(),
210 boost::bind(&server::handle_accept, this, new_session,
211 boost::asio::placeholders::error));
212 }
213
214private:
b32b8144 215 boost::asio::io_context& io_context_;
7c673cae
FG
216 tcp::acceptor acceptor_;
217};
218
219int main(int argc, char* argv[])
220{
221 try
222 {
223 if (argc != 2)
224 {
225 std::cerr << "Usage: server <port>\n";
226 return 1;
227 }
228
b32b8144 229 boost::asio::io_context io_context;
7c673cae
FG
230
231 using namespace std; // For atoi.
b32b8144 232 server s(io_context, atoi(argv[1]));
7c673cae 233
b32b8144 234 io_context.run();
7c673cae
FG
235 }
236 catch (std::exception& e)
237 {
238 std::cerr << "Exception: " << e.what() << "\n";
239 }
240
241 return 0;
242}