summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/src/tests/latency/udp_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/src/tests/latency/udp_server.cpp')
-rw-r--r--3rdparty/asio/src/tests/latency/udp_server.cpp125
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();
+}