]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/example/cpp11/fork/process_per_connection.cpp
2 // process_per_connection.cpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #include <boost/asio/io_context.hpp>
12 #include <boost/asio/ip/tcp.hpp>
13 #include <boost/asio/signal_set.hpp>
14 #include <boost/asio/write.hpp>
17 #include <sys/types.h>
21 using boost::asio::ip::tcp
;
26 server(boost::asio::io_context
& io_context
, unsigned short port
)
27 : io_context_(io_context
),
28 signal_(io_context
, SIGCHLD
),
29 acceptor_(io_context
, {tcp::v4(), port
}),
37 void wait_for_signal()
40 [this](boost::system::error_code
/*ec*/, int /*signo*/)
42 // Only the parent process should check for this signal. We can
43 // determine whether we are in the parent by checking if the acceptor
45 if (acceptor_
.is_open())
47 // Reap completed child processes so that we don't end up with
50 while (waitpid(-1, &status
, WNOHANG
) > 0) {}
59 acceptor_
.async_accept(
60 [this](boost::system::error_code ec
, tcp::socket new_socket
)
64 // Take ownership of the newly accepted socket.
65 socket_
= std::move(new_socket
);
67 // Inform the io_context that we are about to fork. The io_context
68 // cleans up any internal resources, such as threads, that may
69 // interfere with forking.
70 io_context_
.notify_fork(boost::asio::io_context::fork_prepare
);
74 // Inform the io_context that the fork is finished and that this
75 // is the child process. The io_context uses this opportunity to
76 // create any internal file descriptors that must be private to
78 io_context_
.notify_fork(boost::asio::io_context::fork_child
);
80 // The child won't be accepting new connections, so we can close
81 // the acceptor. It remains open in the parent.
84 // The child process is not interested in processing the SIGCHLD
93 // Inform the io_context that the fork is finished (or failed)
94 // and that this is the parent process. The io_context uses this
95 // opportunity to recreate any internal resources that were
96 // cleaned up during preparation for the fork.
97 io_context_
.notify_fork(boost::asio::io_context::fork_parent
);
99 // The parent process can now close the newly accepted socket. It
100 // remains open in the child.
108 std::cerr
<< "Accept error: " << ec
.message() << std::endl
;
116 socket_
.async_read_some(boost::asio::buffer(data_
),
117 [this](boost::system::error_code ec
, std::size_t length
)
124 void write(std::size_t length
)
126 boost::asio::async_write(socket_
, boost::asio::buffer(data_
, length
),
127 [this](boost::system::error_code ec
, std::size_t /*length*/)
134 boost::asio::io_context
& io_context_
;
135 boost::asio::signal_set signal_
;
136 tcp::acceptor acceptor_
;
138 std::array
<char, 1024> data_
;
141 int main(int argc
, char* argv
[])
147 std::cerr
<< "Usage: process_per_connection <port>\n";
151 boost::asio::io_context io_context
;
153 using namespace std
; // For atoi.
154 server
s(io_context
, atoi(argv
[1]));
158 catch (std::exception
& e
)
160 std::cerr
<< "Exception: " << e
.what() << std::endl
;