diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 64b5da6..aebf0f5 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -38,7 +38,7 @@ endif() ExternalProject_Add( boost URL http://switch.dl.sourceforge.net/project/boost/boost/${boost_version}/boost_${boost_version_underscored}.zip - CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=coroutine + CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=coroutine,thread BUILD_COMMAND ./b2 --ignore-site-config --stagedir=${CMAKE_SOURCE_DIR} link=static threading=multi cxxflags=-std=c++11 ${boost_build_type} BUILD_IN_SOURCE 1 INSTALL_COMMAND "" @@ -62,7 +62,7 @@ project(${TEST_SERVER_PROJECT_NAME} CXX) aux_source_directory(${SRC_DIR}/server TEST_SERVER_SRC) add_executable(${TEST_SERVER_PROJECT_NAME} ${TEST_SERVER_SRC}) add_dependencies(${TEST_SERVER_PROJECT_NAME} boost cpputil) -target_link_libraries(${TEST_SERVER_PROJECT_NAME} cpputil ${CMAKE_SOURCE_DIR}/lib/libboost_system.a ${CMAKE_SOURCE_DIR}/lib/libboost_coroutine.a) +target_link_libraries(${TEST_SERVER_PROJECT_NAME} cpputil ${CMAKE_SOURCE_DIR}/lib/libboost_system.a ${CMAKE_SOURCE_DIR}/lib/libboost_thread.a ${CMAKE_SOURCE_DIR}/lib/libboost_coroutine.a ${CMAKE_SOURCE_DIR}/lib/libboost_context.a) install(TARGETS ${TEST_PROJECT_NAME} RUNTIME DESTINATION bin diff --git a/test/server/main.cpp b/test/server/main.cpp index 92871cc..979796c 100644 --- a/test/server/main.cpp +++ b/test/server/main.cpp @@ -1,10 +1,35 @@ -#include "server.h" +#include "session.h" + +#include #include +using tcp = boost::asio::ip::tcp; + +void start_server(std::string address, std::string port) +{ + boost::asio::io_service io_service; + tcp::resolver resolver(io_service); + tcp::resolver::query query(address, port); + tcp::acceptor acceptor(io_service, *resolver.resolve(query)); + + boost::asio::spawn(io_service, [&](boost::asio::yield_context yield){ + for (;;) + { + session* s = new session(io_service); + acceptor.async_accept(s->socket(), yield); + s->start(); + } + }); + + io_service.run(); +} + int main() { - server srv("0.0.0.0", "12345"); - srv.run(); +// server srv("0.0.0.0", "12345"); +// srv.run(); + + start_server("0.0.0.0", "12345"); return 0; } \ No newline at end of file diff --git a/test/server/server.cpp b/test/server/server.cpp deleted file mode 100644 index 93a279f..0000000 --- a/test/server/server.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "server.h" -#include -#include - -server::server(const std::string& address, const std::string& port) -{ - tcp::resolver resolver(_io_service); - tcp::resolver::query query(address, port); - _acceptor = new tcp::acceptor(_io_service, *resolver.resolve(query)); -} - -void server::run() -{ - accept(); - _io_service.run(); -} - -void server::accept(boost::system::error_code ec) -{ - if(!ec) - { - reenter(this) for(;;) - { - _session = new session(_io_service); - yield _acceptor->async_accept(_session->_socket, std::bind(&server::accept, this, std::placeholders::_1)); - std::cout << "new connection started" << std::endl; - _session->start(); - } - } - else - { - std::cout << "error: " << ec.message() << std::endl; - } -} - -server::~server() { - if(_socket) delete _socket; - if(_acceptor) delete _acceptor; -} - -#include diff --git a/test/server/server.h b/test/server/server.h deleted file mode 100644 index 5f9592a..0000000 --- a/test/server/server.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _SERVER_H_ -#define _SERVER_H_ - -#include "session.h" -#include - -class server: boost::asio::coroutine -{ -private: - typedef boost::asio::ip::tcp tcp; - -private: - boost::asio::io_service _io_service; - tcp::acceptor* _acceptor; - tcp::socket* _socket; - session* _session; - -public: - server() = delete ; - server(server& srv) = delete; - server(const std::string& address, const std::string& port); - void run(); - ~server(); - -private: - void accept(boost::system::error_code ec = boost::system::error_code()); -}; - -#endif // _SERVER_H_ \ No newline at end of file diff --git a/test/server/session.cpp b/test/server/session.cpp index 1255d6b..c2f60f7 100644 --- a/test/server/session.cpp +++ b/test/server/session.cpp @@ -1,37 +1,29 @@ #include "session.h" - #include -#include +#include session::session(boost::asio::io_service &io_service): boost::asio::coroutine(), _socket(io_service) { } -void session::start(boost::system::error_code ec, std::size_t bytes_transferred) +void session::start() { - if(!ec) - { - reenter(this) for(;;) // псевдолинейный код - { - std::memset(_data, 0, 128); - yield _socket.async_read_some(boost::asio::buffer(_data, 128), std::bind(&session::start, this, std::placeholders::_1, std::placeholders::_2)); + boost::asio::spawn(_socket.get_io_service(), [this](boost::asio::yield_context yield){ + for(;;) + { + std::size_t bytes = _socket.async_read_some(boost::asio::buffer(_data, 128), yield); - yield _fut = call_async([this]{ + int n = async_call([this]{ int n = std::atoi(_data); return n*n; - }); + }, yield); - yield { - std::string res = std::to_string(_fut.get()) + "\n"; - _socket.async_write_some(boost::asio::buffer(res), std::bind(&session::start, this, std::placeholders::_1, std::placeholders::_2)); - } - } - } - else - { - std::cout << "error: " << ec.message() << std::endl; - delete this; - } + _socket.async_write_some(boost::asio::buffer(std::to_string(n) + "\n"), yield); + } + }); } -#include +boost::asio::ip::tcp::socket& session::socket() +{ + return _socket; +} diff --git a/test/server/session.h b/test/server/session.h index 3cead8d..42bad14 100644 --- a/test/server/session.h +++ b/test/server/session.h @@ -8,7 +8,6 @@ class session: boost::asio::coroutine { private: typedef boost::asio::ip::tcp tcp; - friend class server; private: tcp::socket _socket; @@ -22,17 +21,21 @@ public: session() = delete; session(session&) = delete; session(boost::asio::io_service& io_service); - void start(boost::system::error_code ec = boost::system::error_code(), std::size_t bytes_transferred = 0); + void start(); - template std::future call_async(std::function func) + template R async_call(std::function func, CompletionToken&& token) { - return _pool.add_task([this, &func]{ - R result = func(); - _socket.get_io_service().dispatch(std::bind(&session::start, this, boost::system::error_code(), 0)); - return result; + typename boost::asio::handler_type::type handler(std::forward(token)); + boost::asio::async_result result(handler); + + _pool.add_task([this, handler, &func]{ + _socket.get_io_service().dispatch(std::bind(handler, func())); }); + + return result.get(); } + boost::asio::ip::tcp::socket& socket(); }; #endif // _SESSION_H_ \ No newline at end of file