diff options
Diffstat (limited to '3rdparty/asio/src/tests/latency/udp_server.cpp')
-rw-r--r-- | 3rdparty/asio/src/tests/latency/udp_server.cpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/3rdparty/asio/src/tests/latency/udp_server.cpp b/3rdparty/asio/src/tests/latency/udp_server.cpp new file mode 100644 index 00000000000..a767f4c782a --- /dev/null +++ b/3rdparty/asio/src/tests/latency/udp_server.cpp @@ -0,0 +1,125 @@ +// +// udp_server.cpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <asio/io_context.hpp> +#include <asio/ip/udp.hpp> +#include <boost/shared_ptr.hpp> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <vector> +#include "allocator.hpp" + +using asio::ip::udp; + +#include "yield.hpp" + +class udp_server : coroutine +{ +public: + udp_server(asio::io_context& io_context, + unsigned short port, std::size_t buf_size) : + socket_(io_context, udp::endpoint(udp::v4(), port)), + buffer_(buf_size) + { + } + + void operator()(asio::error_code ec, std::size_t n = 0) + { + reenter (this) for (;;) + { + yield socket_.async_receive_from( + asio::buffer(buffer_), + sender_, ref(this)); + + if (!ec) + { + for (std::size_t i = 0; i < n; ++i) buffer_[i] = ~buffer_[i]; + socket_.send_to(asio::buffer(buffer_, n), sender_, 0, ec); + } + } + } + + friend void* asio_handler_allocate(std::size_t n, udp_server* s) + { + return s->allocator_.allocate(n); + } + + friend void asio_handler_deallocate(void* p, std::size_t, udp_server* s) + { + s->allocator_.deallocate(p); + } + + struct ref + { + explicit ref(udp_server* p) + : p_(p) + { + } + + void operator()(asio::error_code ec, std::size_t n = 0) + { + (*p_)(ec, n); + } + + private: + udp_server* p_; + + friend void* asio_handler_allocate(std::size_t n, ref* r) + { + return asio_handler_allocate(n, r->p_); + } + + friend void asio_handler_deallocate(void* p, std::size_t n, ref* r) + { + asio_handler_deallocate(p, n, r->p_); + } + }; + +private: + udp::socket socket_; + std::vector<unsigned char> buffer_; + udp::endpoint sender_; + allocator allocator_; +}; + +#include "unyield.hpp" + +int main(int argc, char* argv[]) +{ + if (argc != 5) + { + std::fprintf(stderr, + "Usage: udp_server <port1> <nports> " + "<bufsize> {spin|block}\n"); + return 1; + } + + unsigned short first_port = static_cast<unsigned short>(std::atoi(argv[1])); + unsigned short num_ports = static_cast<unsigned short>(std::atoi(argv[2])); + std::size_t buf_size = std::atoi(argv[3]); + bool spin = (std::strcmp(argv[4], "spin") == 0); + + asio::io_context io_context(1); + std::vector<boost::shared_ptr<udp_server> > servers; + + for (unsigned short i = 0; i < num_ports; ++i) + { + unsigned short port = first_port + i; + boost::shared_ptr<udp_server> s(new udp_server(io_context, port, buf_size)); + servers.push_back(s); + (*s)(asio::error_code()); + } + + if (spin) + for (;;) io_context.poll(); + else + io_context.run(); +} |