Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1b765f0

Browse files
committed
WIP: Asynchronous Server Implementation
This is an incremental installment into the asynchronous serverimplementation revamp. The goal here is to isolate the parts that areactually necessary to build client code and move more of theimplementation into externally-linked libraries. This allows us totweak, add features, and generally make the API/ABI more stable forfuture extension and updates.
1 parent8f26ea8 commit1b765f0

File tree

7 files changed

+250
-26
lines changed

7 files changed

+250
-26
lines changed

‎boost/network/include/http/server.hpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#ifndef BOOST_NETWORK_INCLUDE_HTTP_SERVER_HPP_
22
#defineBOOST_NETWORK_INCLUDE_HTTP_SERVER_HPP_
33

4-
// Copyright 2010 Dean Michael Berris
4+
// Copyright 2010-2012 Dean Michael Berris <dberris@google.com>.
5+
// Copyright 2012 Google, Inc.
56
// Distributed under the Boost Software License, Version 1.0.
67
// (See accompanying file LICENSE_1_0.txt or copy at
78
// http://www.boost.org/LICENSE_1_0.txt)

‎boost/network/protocol/http/server/async_impl.hpp‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
#include<boost/function.hpp>
1111
#include<boost/shared_ptr.hpp>
12+
#include<boost/asio/ip/tcp.hpp>
13+
#include<boost/thread/mutex.hpp>
14+
#include<boost/network/protocol/http/server/options.hpp>
1215

1316
namespaceboost {namespacenetwork {namespaceutils {
1417

@@ -22,6 +25,8 @@ struct thread_pool;
2225

2326
namespaceboost {namespacenetwork {namespacehttp {
2427

28+
structrequest;
29+
2530
classasync_server_connection;
2631

2732
classasync_server_impl {
@@ -30,6 +35,7 @@ class async_server_impl {
3035
async_server_impl(server_optionsconst &options,
3136
function<void(requestconst &, connection_ptr)> handler,
3237
utils::thread_pool &thread_pool);
38+
~async_server_impl();
3339
voidrun();
3440
voidstop();
3541
voidlisten();
@@ -40,10 +46,17 @@ class async_server_impl {
4046
asio::io_service *service_;
4147
asio::ip::tcp::acceptor *acceptor_;
4248
shared_ptr<async_server_connection> new_connection_;
43-
mutex listening_mutex_;
44-
bool listening_, owned_service_;
49+
mutex listening_mutex_, stopping_mutex_;
4550
function<void(requestconst &, connection_ptr)> handler_;
4651
utils::thread_pool &pool_;
52+
bool listening_, owned_service_, stopping_;
53+
54+
voidhandle_stop();
55+
voidstart_listening();
56+
voidhandle_accept(system::error_codeconst &ec);
57+
58+
voidset_socket_options(asio::ip::tcp::socket &socket);
59+
voidset_acceptor_options(asio::ip::tcp::acceptor &acceptor);
4760
};
4861

4962
}// namespace http
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
#ifndef BOOST_NETWORK_PROTOCOL_HTTP_SERVER_ASYNC_IMPL_IPP_20120318
2+
#defineBOOST_NETWORK_PROTOCOL_HTTP_SERVER_ASYNC_IMPL_IPP_20120318
3+
4+
// Copyright 2012 Dean Michael Berris <dberris@google.com>.
5+
// Copyright 2012 Google, Inc.
6+
// Distributed under the Boost Software License, Version 1.0.
7+
// (See accompanying file LICENSE_1_0.txt or copy at
8+
// http://www.boost.org/LICENSE_1_0.txt)
9+
10+
#include<boost/network/protocol/http/server/async_impl.hpp>
11+
#include<boost/asio/io_service.hpp>
12+
#include<boost/asio/ip/tcp.hpp>
13+
#include<boost/asio/placeholders.hpp>
14+
#include<boost/bind.hpp>
15+
#include<boost/network/detail/debug.hpp>
16+
17+
namespaceboost {namespacenetwork {namespacehttp {
18+
19+
async_server_impl::async_server_impl(server_optionsconst &options,
20+
function<void(requestconst &, connection_ptr)> handler,
21+
utils::thread_pool &thread_pool)
22+
: options_(options)
23+
, address_(options.address())
24+
, port_(options.port())
25+
, service_(options.io_service())
26+
, acceptor_(0)
27+
, new_connection_()
28+
, listening_mutex_()
29+
, stopping_mutex_()
30+
, handler_(handler)
31+
, pool_(thread_pool)
32+
, listening_(false)
33+
, owned_service_(false)
34+
, stopping_(false) {
35+
if (service_ ==0) {
36+
service_ =new (std::nothrow) asio::io_service;
37+
owned_service_ =true;
38+
}
39+
BOOST_ASSERT(service_ !=0);
40+
acceptor_ =new (std::nothrow)asio::ip::tcp::acceptor(*service_);
41+
BOOST_ASSERT(acceptor_ !=0);
42+
}
43+
44+
async_server_impl::~async_server_impl() {
45+
if (owned_service_)delete service_;
46+
delete acceptor_;
47+
}
48+
49+
voidasync_server_impl::run() {
50+
listen();
51+
service_->run();
52+
}
53+
54+
voidasync_server_impl::stop() {
55+
lock_guard<mutex>listening_lock(listening_mutex_);
56+
if (listening_) {
57+
lock_guard<mutex>stopping_lock(stopping_mutex_);
58+
stopping_ =true;
59+
system::error_code ignored;
60+
acceptor_->close(ignored);
61+
listening_ =false;
62+
service_->post(
63+
boost::bind(&async_server_impl::handle_stop,this));
64+
}
65+
}
66+
67+
voidasync_server_impl::listen() {
68+
lock_guard<mutex>listening_lock(listening_mutex_);
69+
BOOST_NETWORK_MESSAGE("listening on" << address_ <<':' << port_);
70+
if (!listening_)start_listening();
71+
if (!listening_) {
72+
BOOST_NETWORK_MESSAGE("error listening on" << address_ <<':' << port_);
73+
BOOST_THROW_EXCEPTION(std::runtime_error("Error listening on provided address:port."));
74+
}
75+
}
76+
77+
voidasync_server_impl::handle_stop() {
78+
lock_guard<mutex>stopping_lock(stopping_mutex_);
79+
// A user may have stopped listening again before the stop command is
80+
// reached.
81+
if (stopping_) service_->stop();
82+
}
83+
84+
voidasync_server_impl::handle_accept(boost::system::error_codeconst & ec) {
85+
{
86+
lock_guard<mutex>stopping_lock(stopping_mutex_);
87+
// We dont want to add another handler instance, and we dont want to know
88+
// about errors for a socket we dont need anymore.
89+
if (stopping_)return;
90+
}
91+
if (!ec) {
92+
set_socket_options(new_connection_->socket());
93+
new_connection_->start();
94+
new_connection_.reset(
95+
newasync_server_connection(*service_, handler_, pool_));
96+
acceptor_->async_accept(
97+
new_connection_->socket(),
98+
boost::bind(
99+
&async_server_impl::handle_accept,
100+
this,
101+
asio::placeholders::error));
102+
}else {
103+
BOOST_NETWORK_MESSAGE("Error accepting connection, reason:" << ec);
104+
}
105+
}
106+
107+
voidasync_server_impl::start_listening() {
108+
using asio::ip::tcp;
109+
system::error_code error;
110+
service_->reset();// allows repeated cycles of run->stop->run
111+
tcp::resolverresolver(*service_);
112+
tcp::resolver::queryquery(address_, port_);
113+
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query, error);
114+
if (error) {
115+
BOOST_NETWORK_MESSAGE("error resolving '" << address_ <<':' << port_);
116+
BOOST_THROW_EXCEPTION(std::runtime_error("Error resolving address:port combination."));
117+
}
118+
tcp::endpoint endpoint = *endpoint_iterator;
119+
acceptor_->open(endpoint.protocol(), error);
120+
if (error) {
121+
BOOST_NETWORK_MESSAGE("error opening socket:" << address_ <<":" << port_);
122+
BOOST_THROW_EXCEPTION(std::runtime_error("Error opening socket."));
123+
}
124+
set_acceptor_options(*acceptor_);
125+
acceptor_->bind(endpoint, error);
126+
if (error) {
127+
BOOST_NETWORK_MESSAGE("error binding socket:" << address_ <<":" << port_);
128+
BOOST_THROW_EXCEPTION(std::runtime_error("Error binding socket."));
129+
}
130+
acceptor_->listen(asio::socket_base::max_connections, error);
131+
if (error) {
132+
BOOST_NETWORK_MESSAGE("error listening on socket: '" << error <<"' on" << address_ <<":" << port_);
133+
BOOST_THROW_EXCEPTION(std::runtime_error("Error listening on socket."));
134+
}
135+
new_connection_.reset(newasync_server_connection(*service_, handler_, pool_));
136+
acceptor_->async_accept(
137+
new_connection_->socket(),
138+
boost::bind(
139+
&async_server_impl::handle_accept,
140+
this,
141+
asio::placeholders::error));
142+
listening_ =true;
143+
lock_guard<mutex>stopping_lock(stopping_mutex_);
144+
stopping_ =false;// if we were in the process of stopping, we revoke that command and continue listening
145+
BOOST_NETWORK_MESSAGE("now listening on '" << address_ <<":" << port_ <<"'");
146+
}
147+
148+
voidasync_server_impl::set_socket_options(asio::ip::tcp::socket &socket) {
149+
system::error_code ignored;
150+
socket.non_blocking(options_.non_blocking_io(), ignored);
151+
if (options_.linger()) {
152+
asio::ip::tcp::socket::lingerlinger(true, options_.linger_timeout());
153+
socket.set_option(linger, ignored);
154+
}
155+
if (int buf_size = options_.receive_buffer_size() >=0) {
156+
asio::ip::tcp::socket::receive_buffer_sizereceive_buffer_size(buf_size);
157+
socket.set_option(receive_buffer_size, ignored);
158+
}
159+
if (int buf_size = options_.send_buffer_size() >=0) {
160+
asio::ip::tcp::socket::send_buffer_sizesend_buffer_size(buf_size);
161+
socket.set_option(send_buffer_size, ignored);
162+
}
163+
if (int buf_size = options_.receive_low_watermark() >=0) {
164+
asio::ip::tcp::socket::receive_low_watermarkreceive_low_watermark(buf_size);
165+
socket.set_option(receive_low_watermark, ignored);
166+
}
167+
if (int buf_size = options_.send_low_watermark() >=0) {
168+
asio::ip::tcp::socket::send_low_watermarksend_low_watermark(buf_size);
169+
socket.set_option(send_low_watermark, ignored);
170+
}
171+
}
172+
173+
voidasync_server_impl::set_acceptor_options(asio::ip::tcp::acceptor &acceptor) {
174+
system::error_code ignored;
175+
acceptor.set_option(
176+
asio::ip::tcp::acceptor::reuse_address(options_.reuse_address()),
177+
ignored);
178+
acceptor.set_option(
179+
asio::ip::tcp::acceptor::enable_connection_aborted(options_.report_aborted()),
180+
ignored);
181+
}
182+
183+
}// namespace http
184+
185+
}// namespace network
186+
187+
}// namespace boost
188+
189+
#endif// BOOST_NETWORK_PROTOCOL_HTTP_SERVER_ASYNC_IMPL_IPP_20120318

‎boost/network/protocol/http/server/options.hpp‎

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,46 +28,46 @@ class server_options {
2828
voidswap(server_options &other);
2929
server_options&operator=(server_options rhs);
3030

31-
server_options&address(std::stringconst &address="0.0.0.0");
31+
server_options&address(std::stringconst &address);
3232
std::stringconstaddress()const;
3333

34-
server_options&port(std::stringconst &port="80");
34+
server_options&port(std::stringconst &port);
3535
std::stringconstport()const;
3636

37-
server_options&io_service(asio::io_service *service =0);
37+
server_options&io_service(asio::io_service *service);
3838
asio::io_service *io_service()const;
3939

40-
server_options&reuse_address(bool setting=true);
41-
boolreuse_address();
40+
server_options&reuse_address(bool setting);
41+
boolreuse_address()const;
4242

43-
server_options&report_aborted(bool setting=false);
44-
boolreport_aborted();
43+
server_options&report_aborted(bool setting);
44+
boolreport_aborted()const;
4545

4646
// Set the receive buffer size for a socket. -1 means just use the default.
47-
server_options&receive_buffer_size(int buffer_size=-1);
48-
intreceive_buffer_size();
47+
server_options&receive_buffer_size(int buffer_size);
48+
intreceive_buffer_size()const;
4949

5050
// Set the send buffer size for a socket. -1 means just use the default.
51-
server_options&send_buffer_size(int buffer_size=-1);
52-
intsend_buffer_size();
51+
server_options&send_buffer_size(int buffer_size);
52+
intsend_buffer_size()const;
5353

5454
// Set the receive low watermark for a socket. -1 means just use the default.
55-
server_options&receive_low_watermark(int low_watermark=-1);
56-
intreceive_low_watermark();
55+
server_options&receive_low_watermark(int low_watermark);
56+
intreceive_low_watermark()const;
5757

5858
// Set the send low watermark for a socket. -1 means just use the default.
59-
server_options&send_low_watermark(int low_watermark=-1);
60-
intsend_low_watermark();
59+
server_options&send_low_watermark(int low_watermark);
60+
intsend_low_watermark()const;
6161

62-
server_options&non_blocking_io(bool setting=true);
63-
boolnon_blocking_io();
62+
server_options&non_blocking_io(bool setting);
63+
boolnon_blocking_io()const;
6464

65-
server_options&linger(bool setting=false);
66-
boollinger();
65+
server_options&linger(bool setting);
66+
boollinger()const;
6767

6868
// Set the socket linger timeout. This is only relevant if linger is true
6969
// (see linger above). -1 means just use the default.
70-
server_options&linger_timeout(int setting=-1);
70+
server_options&linger_timeout(int setting);
7171
intlinger_timeout();
7272

7373
private:

‎libs/network/src/CMakeLists.txt‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,18 @@ if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU)
1717
endif()
1818
endforeach(src_file)
1919

20-
set(CPP-NETLIB_HTTP_SERVER_SRCS server_request_parsers_impl.cpp)
21-
add_library(cppnetlib-server-parsers ${CPP-NETLIB_HTTP_SERVER_SRCS})
20+
set(CPP-NETLIB_HTTP_SERVER_PARSERS_SRCS server_request_parsers_impl.cpp)
21+
add_library(cppnetlib-http-server-parsers ${CPP-NETLIB_HTTP_SERVER_PARSERS_SRCS})
22+
foreach (src_file ${CPP-NETLIB_HTTP_SERVER_PARSERS_SRCS})
23+
if (${CMAKE_CXX_COMPILER_ID}MATCHES GNU)
24+
set_source_files_properties(${src_file}
25+
PROPERTIESCOMPILE_FLAGS"-Wall -Werror")
26+
endif()
27+
endforeach(src_file)
28+
29+
set(CPP-NETLIB_HTTP_SERVER_SRCS
30+
http/server_async_impl.cpp)
31+
add_library(cppnetlib-http-servers ${CPP-NETLIB_HTTP_SERVER_SRCS})
2232
foreach (src_file ${CPP-NETLIB_HTTP_SERVER_SRCS})
2333
if (${CMAKE_CXX_COMPILER_ID}MATCHES GNU)
2434
set_source_files_properties(${src_file}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2012 Dean Michael Berris <dberris@google.com>.
2+
// Copyright 2012 Google, Inc.
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// (See accompanying file LICENSE_1_0.txt or copy at
5+
// http://www.boost.org/LICENSE_1_0.txt)
6+
7+
#include<boost/network/protocol/http/server/async_impl.ipp>

‎libs/network/test/http/CMakeLists.txt‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ if (Boost_FOUND)
8484
PROPERTIESCOMPILE_FLAGS"-Wall")
8585
endif()
8686
add_executable(cpp-netlib-http-${test}${test}.cpp)
87-
target_link_libraries(cpp-netlib-http-${test}${Boost_LIBRARIES}${CMAKE_THREAD_LIBS_INIT} cppnetlib-server-parsers)
87+
target_link_libraries(cpp-netlib-http-${test}
88+
${Boost_LIBRARIES}
89+
${CMAKE_THREAD_LIBS_INIT}
90+
cppnetlib-http-servers
91+
cppnetlib-http-server-parsers)
8892
set_target_properties(cpp-netlib-http-${test}
8993
PROPERTIESRUNTIME_OUTPUT_DIRECTORY ${CPP-NETLIB_BINARY_DIR}/tests)
9094
add_test(cpp-netlib-http-${test}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp