From 7c077d9a952df609f991a91491e9df2d1cff1a3f Mon Sep 17 00:00:00 2001 From: Marcos Bento Date: Mon, 2 Sep 2024 18:10:47 +0100 Subject: [PATCH] Use io_context instead of the deprecated io_service - User boost::asio::bind_executor instead of the deprecated io_service::wrap() Re ECFLOW-1973 --- .../src/Server/doc/disk_io.ddoc | 12 +++++------ libs/base/src/ecflow/base/Client.cpp | 10 +++++----- libs/base/src/ecflow/base/Client.hpp | 2 +- libs/base/src/ecflow/base/Connection.cpp | 2 +- libs/base/src/ecflow/base/Connection.hpp | 2 +- libs/base/src/ecflow/base/SslClient.cpp | 10 +++++----- libs/base/src/ecflow/base/SslClient.hpp | 2 +- .../base/src/ecflow/base/cts/user/PlugCmd.cpp | 10 +++++----- libs/base/src/ecflow/base/ssl_connection.cpp | 4 ++-- libs/base/src/ecflow/base/ssl_connection.hpp | 2 +- .../src/ecflow/client/ClientInvoker.cpp | 20 +++++++++---------- libs/server/src/ecflow/server/BaseServer.cpp | 14 ++++++------- libs/server/src/ecflow/server/BaseServer.hpp | 6 +++--- .../server/src/ecflow/server/CheckPtSaver.cpp | 12 +++++------ .../server/src/ecflow/server/CheckPtSaver.hpp | 2 +- .../src/ecflow/server/NodeTreeTraverser.cpp | 5 +++-- .../src/ecflow/server/NodeTreeTraverser.hpp | 2 +- .../src/ecflow/server/PeriodicScheduler.hpp | 9 +++++---- libs/server/src/ecflow/server/Server.cpp | 6 +++--- libs/server/src/ecflow/server/Server.hpp | 2 +- libs/server/src/ecflow/server/ServerMain.cpp | 20 +++++++++---------- libs/server/src/ecflow/server/SslServer.cpp | 6 +++--- libs/server/src/ecflow/server/SslServer.hpp | 2 +- .../server/src/ecflow/server/SslTcpServer.cpp | 6 +++--- .../server/src/ecflow/server/SslTcpServer.hpp | 2 +- .../src/ecflow/server/TcpBaseServer.cpp | 14 ++++++------- .../src/ecflow/server/TcpBaseServer.hpp | 4 ++-- libs/server/src/ecflow/server/TcpServer.cpp | 6 +++--- libs/server/src/ecflow/server/TcpServer.hpp | 2 +- libs/server/test/TestPeriodicScheduler.cpp | 16 +++++++-------- libs/server/test/TestServer.cpp | 6 +++--- libs/udp/src/ecflow/udp/UDPClient.hpp | 12 +++++------ libs/udp/src/ecflow/udp/UDPServer.hpp | 12 +++++------ 33 files changed, 122 insertions(+), 120 deletions(-) diff --git a/docs/internal_team_notes/src/Server/doc/disk_io.ddoc b/docs/internal_team_notes/src/Server/doc/disk_io.ddoc index f2acd6faa..d24eea7bb 100644 --- a/docs/internal_team_notes/src/Server/doc/disk_io.ddoc +++ b/docs/internal_team_notes/src/Server/doc/disk_io.ddoc @@ -79,7 +79,7 @@ instead of requiring a type (i.e. task must inherit from process), provides more class thread_pool { private: - boost::asio::io_service io_service_; + boost::asio::io_service io_; boost::asio::io_service::work work_; boost::thread_group threads_; std::size_t available_; @@ -88,13 +88,13 @@ public: /// @brief Constructor. thread_pool( std::size_t pool_size ) - : work_( io_service_ ), + : work_( io_ ), available_( pool_size ) { for ( std::size_t i = 0; i < pool_size; ++i ) { threads_.create_thread( boost::bind( &boost::asio::io_service::run, - &io_service_ ) ); + &io_ ) ); } } @@ -102,7 +102,7 @@ public: ~thread_pool() { // Force all threads to return from io_service::run(). - io_service_.stop(); + io_.stop(); // Suppress all exceptions. try @@ -125,7 +125,7 @@ public: --available_; // Post a wrapped task into the queue. - io_service_.post( boost::bind( &thread_pool::wrap_task, this, + io_.post( boost::bind( &thread_pool::wrap_task, this, boost::function< void() >( task ) ) ); } @@ -319,4 +319,4 @@ private: bool m_terminate; boost::asio::io_service *m_ioService; boost::thread *m_serviceThread; -} \ No newline at end of file +} diff --git a/libs/base/src/ecflow/base/Client.cpp b/libs/base/src/ecflow/base/Client.cpp index 9d1debe48..b47f2a795 100644 --- a/libs/base/src/ecflow/base/Client.cpp +++ b/libs/base/src/ecflow/base/Client.cpp @@ -29,7 +29,7 @@ /// If we do not have a timeout, it will hang indefinitely /// Constructor starts the asynchronous connect operation. -Client::Client(boost::asio::io_service& io_service, +Client::Client(boost::asio::io_context& io, Cmd_ptr cmd_ptr, const std::string& host, const std::string& port, @@ -37,8 +37,8 @@ Client::Client(boost::asio::io_service& io_service, : stopped_(false), host_(host), port_(port), - connection_(io_service), - deadline_(io_service), + connection_(io), + deadline_(io), timeout_(timeout) { /// Avoid sending a NULL request to the server if (!cmd_ptr.get()) @@ -60,7 +60,7 @@ Client::Client(boost::asio::io_service& io_service, // Host name resolution is performed using a resolver, where host and service // names(or ports) are looked up and converted into one or more end points - boost::asio::ip::tcp::resolver resolver(io_service); + boost::asio::ip::tcp::resolver resolver(io); boost::asio::ip::tcp::resolver::query query(host_, port_); boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); @@ -299,7 +299,7 @@ void Client::handle_read(const boost::system::error_code& e) { throw std::runtime_error(ss.str()); } - // Since we are not starting a new operation the io_service will run out of + // Since we are not starting a new operation the io_context will run out of // work to do and the Client will exit. } diff --git a/libs/base/src/ecflow/base/Client.hpp b/libs/base/src/ecflow/base/Client.hpp index d5ed73ad8..da96b3403 100644 --- a/libs/base/src/ecflow/base/Client.hpp +++ b/libs/base/src/ecflow/base/Client.hpp @@ -28,7 +28,7 @@ class Client { public: /// Constructor starts the asynchronous connect operation. - Client(boost::asio::io_service& io_service, + Client(boost::asio::io_context& io, Cmd_ptr cmd_ptr, const std::string& host, const std::string& port, diff --git a/libs/base/src/ecflow/base/Connection.cpp b/libs/base/src/ecflow/base/Connection.cpp index c7ebb69b0..6a15b07c6 100644 --- a/libs/base/src/ecflow/base/Connection.cpp +++ b/libs/base/src/ecflow/base/Connection.cpp @@ -22,7 +22,7 @@ connection::~connection() { #endif } -connection::connection(boost::asio::io_service& io_service) : socket_(io_service) { +connection::connection(boost::asio::io_context& io) : socket_(io) { #ifdef DEBUG_CONNECTION if (Ecf::server()) std::cout << "SERVER: Connection::connection\n"; diff --git a/libs/base/src/ecflow/base/Connection.hpp b/libs/base/src/ecflow/base/Connection.hpp index 06373778b..4d5043d57 100644 --- a/libs/base/src/ecflow/base/Connection.hpp +++ b/libs/base/src/ecflow/base/Connection.hpp @@ -45,7 +45,7 @@ class connection { public: ~connection(); - explicit connection(boost::asio::io_service& io_service); + explicit connection(boost::asio::io_context& io); boost::asio::ip::tcp::socket& socket() { return socket_; } boost::asio::ip::tcp::socket& socket_ll() { return socket_; } diff --git a/libs/base/src/ecflow/base/SslClient.cpp b/libs/base/src/ecflow/base/SslClient.cpp index 284024864..2751acefa 100644 --- a/libs/base/src/ecflow/base/SslClient.cpp +++ b/libs/base/src/ecflow/base/SslClient.cpp @@ -27,7 +27,7 @@ /// If we do not have a timeout, it will hang indefinitely /// Constructor starts the asynchronous connect operation. -SslClient::SslClient(boost::asio::io_service& io_service, +SslClient::SslClient(boost::asio::io_context& io, boost::asio::ssl::context& context, Cmd_ptr cmd_ptr, const std::string& host, @@ -36,8 +36,8 @@ SslClient::SslClient(boost::asio::io_service& io_service, : stopped_(false), host_(host), port_(port), - connection_(io_service, context), - deadline_(io_service), + connection_(io, context), + deadline_(io), timeout_(timeout) { /// Avoid sending a NULL request to the server if (!cmd_ptr.get()) @@ -60,7 +60,7 @@ SslClient::SslClient(boost::asio::io_service& io_service, // Host name resolution is performed using a resolver, where host and service // names(or ports) are looked up and converted into one or more end points - boost::asio::ip::tcp::resolver resolver(io_service); + boost::asio::ip::tcp::resolver resolver(io); boost::asio::ip::tcp::resolver::query query(host_, port_); boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); @@ -331,7 +331,7 @@ void SslClient::handle_read(const boost::system::error_code& e) { throw std::runtime_error(ss.str()); } - // Since we are not starting a new operation the io_service will run out of + // Since we are not starting a new operation the io_context will run out of // work to do and the Client will exit. } diff --git a/libs/base/src/ecflow/base/SslClient.hpp b/libs/base/src/ecflow/base/SslClient.hpp index da1f0cea7..112c478cc 100644 --- a/libs/base/src/ecflow/base/SslClient.hpp +++ b/libs/base/src/ecflow/base/SslClient.hpp @@ -26,7 +26,7 @@ class SslClient { public: /// Constructor starts the asynchronous connect operation. - SslClient(boost::asio::io_service& io_service, + SslClient(boost::asio::io_context& io, boost::asio::ssl::context& context, Cmd_ptr cmd_ptr, const std::string& host, diff --git a/libs/base/src/ecflow/base/cts/user/PlugCmd.cpp b/libs/base/src/ecflow/base/cts/user/PlugCmd.cpp index 4c64c0a48..f7e9e24c6 100644 --- a/libs/base/src/ecflow/base/cts/user/PlugCmd.cpp +++ b/libs/base/src/ecflow/base/cts/user/PlugCmd.cpp @@ -173,7 +173,7 @@ STC_Cmd_ptr PlugCmd::doHandleRequest(AbstractServer* as) const { // Server is acting like a client, Send MoveCmd to another server // The source should end up being copied, when sent to remote server ServerReply server_reply; - boost::asio::io_service io_service; + boost::asio::io_context io; #ifdef ECF_OPENSSL if (!as->ssl().empty()) { ecf::Openssl openssl; @@ -181,8 +181,8 @@ STC_Cmd_ptr PlugCmd::doHandleRequest(AbstractServer* as) const { throw std::runtime_error("PlugCmd::doHandleRequest Could not enable ssl for " + as->ssl()); openssl.init_for_client(); - SslClient theClient(io_service, openssl.context(), cts_cmd, host, port); - io_service.run(); + SslClient theClient(io, openssl.context(), cts_cmd, host, port); + io.run(); theClient.handle_server_response(server_reply, false /* debug */); if (server_reply.client_request_failed()) { throw std::runtime_error(server_reply.error_msg()); @@ -190,8 +190,8 @@ STC_Cmd_ptr PlugCmd::doHandleRequest(AbstractServer* as) const { } else { #endif - Client theClient(io_service, cts_cmd, host, port); - io_service.run(); + Client theClient(io, cts_cmd, host, port); + io.run(); theClient.handle_server_response(server_reply, false /* debug */); if (server_reply.client_request_failed()) { throw std::runtime_error(server_reply.error_msg()); diff --git a/libs/base/src/ecflow/base/ssl_connection.cpp b/libs/base/src/ecflow/base/ssl_connection.cpp index 0d49b724e..25e5583fa 100644 --- a/libs/base/src/ecflow/base/ssl_connection.cpp +++ b/libs/base/src/ecflow/base/ssl_connection.cpp @@ -22,8 +22,8 @@ ssl_connection::~ssl_connection() { #endif } -ssl_connection::ssl_connection(boost::asio::io_service& io_service, boost::asio::ssl::context& context) - : socket_(io_service, context) { +ssl_connection::ssl_connection(boost::asio::io_context& io, boost::asio::ssl::context& context) + : socket_(io, context) { #ifdef DEBUG_CONNECTION if (Ecf::server()) std::cout << "SERVER: ssl_connection::ssl_connection\n"; diff --git a/libs/base/src/ecflow/base/ssl_connection.hpp b/libs/base/src/ecflow/base/ssl_connection.hpp index 279cc9069..f9d47c82c 100644 --- a/libs/base/src/ecflow/base/ssl_connection.hpp +++ b/libs/base/src/ecflow/base/ssl_connection.hpp @@ -49,7 +49,7 @@ class ssl_connection { public: ~ssl_connection(); - ssl_connection(boost::asio::io_service& io_service, boost::asio::ssl::context& context); + ssl_connection(boost::asio::io_context& io, boost::asio::ssl::context& context); bool verify_certificate(bool preverified, boost::asio::ssl::verify_context& ctx); /// Get the underlying socket. Used for making a connection or for accepting diff --git a/libs/client/src/ecflow/client/ClientInvoker.cpp b/libs/client/src/ecflow/client/ClientInvoker.cpp index 76f34aa6c..40b7eef5f 100644 --- a/libs/client/src/ecflow/client/ClientInvoker.cpp +++ b/libs/client/src/ecflow/client/ClientInvoker.cpp @@ -366,7 +366,7 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const { int no_of_tries = connection_attempts_; while (no_of_tries > 0) { try { - /// *** Each call to io_service.run(); is a *REQUEST* to the server *** + /// *** Each call to io_context::run(); is a *REQUEST* to the server *** /// *** Hence we *MUST* clear the server_reply before each call ******* /// *** Found during zombie test. i.e when blocking, we were responding to previous, reply, since /// server_reply was not being reset *Note* server_reply_.client_handle_ is kept until the next call @@ -392,13 +392,13 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const { << ")<<<" << endl; } - boost::asio::io_service io_service; + boost::asio::io_context io; #ifdef ECF_OPENSSL if (clientEnv_.ssl()) { clientEnv_.openssl().init_for_client(); - SslClient theClient(io_service, + SslClient theClient(io, clientEnv_.openssl().context(), cts_cmd, clientEnv_.host(), @@ -406,12 +406,12 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const { clientEnv_.connect_timeout()); { #ifdef DEBUG_PERF - ecf::ScopedDurationTimer my_timer(" io_service.run()"); + ecf::ScopedDurationTimer my_timer(" io.run()"); #endif - io_service.run(); + io.run(); } if (clientEnv_.debug()) - cout << TimeStamp::now() << "ClientInvoker: >>> After: io_service.run() <<<" << endl; + cout << TimeStamp::now() << "ClientInvoker: >>> After: io_context::run() <<<" << endl; /// Let see how the server responded if at all. try { @@ -429,15 +429,15 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const { else { #endif Client theClient( - io_service, cts_cmd, clientEnv_.host(), clientEnv_.port(), clientEnv_.connect_timeout()); + io, cts_cmd, clientEnv_.host(), clientEnv_.port(), clientEnv_.connect_timeout()); { #ifdef DEBUG_PERF - ecf::ScopedDurationTimer my_timer(" io_service.run()"); + ecf::ScopedDurationTimer my_timer(" io.run()"); #endif - io_service.run(); + io.run(); } if (clientEnv_.debug()) - cout << TimeStamp::now() << "ClientInvoker: >>> After: io_service.run() <<<" << endl; + cout << TimeStamp::now() << "ClientInvoker: >>> After: io_context::run() <<<" << endl; /// Let see how the server responded if at all. try { diff --git a/libs/server/src/ecflow/server/BaseServer.cpp b/libs/server/src/ecflow/server/BaseServer.cpp index 4726be98f..40370a826 100644 --- a/libs/server/src/ecflow/server/BaseServer.cpp +++ b/libs/server/src/ecflow/server/BaseServer.cpp @@ -33,12 +33,12 @@ using namespace std; using namespace ecf; /// Constructor opens the acceptor and starts waiting for the first incoming connection. -BaseServer::BaseServer(boost::asio::io_service& io_service, ServerEnvironment& serverEnv) - : io_service_(io_service), - signals_(io_service), +BaseServer::BaseServer(boost::asio::io_context& io, ServerEnvironment& serverEnv) + : io_(io), + signals_(io), defs_(Defs::create()), // ECFLOW-182 - traverser_(this, io_service, serverEnv), - checkPtSaver_(this, io_service, &serverEnv), + traverser_(this, io, serverEnv), + checkPtSaver_(this, io, &serverEnv), serverState_(SState::HALTED), serverEnv_(serverEnv) { if (serverEnv_.debug()) @@ -498,9 +498,9 @@ bool BaseServer::debug() const { } void BaseServer::sigterm_signal_handler() { - if (io_service_.stopped()) { + if (io_.stopped()) { if (serverEnv_.debug()) - cout << "-->BaseServer::sigterm_signal_handler(): io_service is stopped returning " << endl; + cout << "-->BaseServer::sigterm_signal_handler(): io_context has stopped returning " << endl; return; } diff --git a/libs/server/src/ecflow/server/BaseServer.hpp b/libs/server/src/ecflow/server/BaseServer.hpp index 7f781d445..cdd428141 100644 --- a/libs/server/src/ecflow/server/BaseServer.hpp +++ b/libs/server/src/ecflow/server/BaseServer.hpp @@ -32,7 +32,7 @@ class BaseServer : public AbstractServer { public: /// Constructor opens the acceptor and starts waiting for the first incoming /// connection. - explicit BaseServer(boost::asio::io_service& io_service, ServerEnvironment&); + explicit BaseServer(boost::asio::io_context& io, ServerEnvironment&); ~BaseServer() override; void handle_terminate(); @@ -88,8 +88,8 @@ class BaseServer : public AbstractServer { void sigterm_signal_handler(); protected: - /// The io_service used to perform asynchronous operations. - boost::asio::io_service& io_service_; + /// The io_context used to perform asynchronous operations. + boost::asio::io_context& io_; /// The signal_set is used to register for automatic check pointing boost::asio::signal_set signals_; diff --git a/libs/server/src/ecflow/server/CheckPtSaver.cpp b/libs/server/src/ecflow/server/CheckPtSaver.cpp index 7dbc301bc..21d6916a5 100644 --- a/libs/server/src/ecflow/server/CheckPtSaver.cpp +++ b/libs/server/src/ecflow/server/CheckPtSaver.cpp @@ -30,7 +30,7 @@ using namespace ecf; //------------------------------------------------------------------------------------- -CheckPtSaver::CheckPtSaver(BaseServer* s, boost::asio::io_service& io, const ServerEnvironment* serverEnv) +CheckPtSaver::CheckPtSaver(BaseServer* s, boost::asio::io_context& io, const ServerEnvironment* serverEnv) : server_(s), timer_(io, boost::posix_time::seconds(0)), firstTime_(true), @@ -71,13 +71,13 @@ void CheckPtSaver::start() { if (firstTime_) { firstTime_ = false; timer_.expires_from_now(boost::posix_time::seconds(serverEnv_->checkPtInterval())); - timer_.async_wait( - server_->io_service_.wrap([this](const boost::system::error_code& error) { periodicSaveCheckPt(error); })); + timer_.async_wait(boost::asio::bind_executor( + server_->io_, [this](const boost::system::error_code& error) { periodicSaveCheckPt(error); })); } } void CheckPtSaver::stop() { // The server is stopped by cancelling all outstanding asynchronous - // operations. Once all operations have finished the io_service::run() call + // operations. Once all operations have finished the io_context::run() call // will exit. #ifdef DEBUG_CHECKPT std::cout << " CheckPtSaver::stop() check_mode: " << serverEnv_->check_mode_str() @@ -174,8 +174,8 @@ void CheckPtSaver::periodicSaveCheckPt(const boost::system::error_code& error) { /// Appears that expires_from_now is more accurate then expires_at timer_.expires_from_now(boost::posix_time::seconds(serverEnv_->checkPtInterval())); - timer_.async_wait( - server_->io_service_.wrap([this](const boost::system::error_code& error) { periodicSaveCheckPt(error); })); + timer_.async_wait(boost::asio::bind_executor( + server_->io_, [this](const boost::system::error_code& error) { periodicSaveCheckPt(error); })); } void CheckPtSaver::doSave() const { diff --git a/libs/server/src/ecflow/server/CheckPtSaver.hpp b/libs/server/src/ecflow/server/CheckPtSaver.hpp index d6538e6e8..6a8198c7f 100644 --- a/libs/server/src/ecflow/server/CheckPtSaver.hpp +++ b/libs/server/src/ecflow/server/CheckPtSaver.hpp @@ -29,7 +29,7 @@ class BaseServer; class CheckPtSaver { public: - CheckPtSaver(BaseServer* s, boost::asio::io_service& io, const ServerEnvironment*); + CheckPtSaver(BaseServer* s, boost::asio::io_context& io, const ServerEnvironment*); // Disable copy (and move) semantics CheckPtSaver(const CheckPtSaver&) = delete; const CheckPtSaver& operator=(const CheckPtSaver&) = delete; diff --git a/libs/server/src/ecflow/server/NodeTreeTraverser.cpp b/libs/server/src/ecflow/server/NodeTreeTraverser.cpp index bed41b8a8..29a959da3 100644 --- a/libs/server/src/ecflow/server/NodeTreeTraverser.cpp +++ b/libs/server/src/ecflow/server/NodeTreeTraverser.cpp @@ -35,7 +35,7 @@ using namespace boost::posix_time; // Hence we poll every second, and check it against the minute boundary // ************************************************************************ -NodeTreeTraverser::NodeTreeTraverser(BaseServer* s, boost::asio::io_service& io, const ServerEnvironment& serverEnv) +NodeTreeTraverser::NodeTreeTraverser(BaseServer* s, boost::asio::io_context& io, const ServerEnvironment& serverEnv) : server_(s), serverEnv_(serverEnv), timer_(io, boost::posix_time::seconds(0)), @@ -284,7 +284,8 @@ void NodeTreeTraverser::start_timer() { /// Appears that expires_from_now is more accurate then expires_at i.e timer_.expires_at( timer_.expires_at() + /// boost::posix_time::seconds( poll_at ) ); timer_.expires_from_now(boost::posix_time::seconds(1)); - timer_.async_wait(server_->io_service_.wrap([this](const boost::system::error_code& error) { traverse(error); })); + timer_.async_wait( + boost::asio::bind_executor(server_->io_, [this](const boost::system::error_code& error) { traverse(error); })); } void NodeTreeTraverser::traverse(const boost::system::error_code& error) { diff --git a/libs/server/src/ecflow/server/NodeTreeTraverser.hpp b/libs/server/src/ecflow/server/NodeTreeTraverser.hpp index 4c1bf5dff..f9e2e5df9 100644 --- a/libs/server/src/ecflow/server/NodeTreeTraverser.hpp +++ b/libs/server/src/ecflow/server/NodeTreeTraverser.hpp @@ -30,7 +30,7 @@ class ServerEnvironment; class NodeTreeTraverser { public: - NodeTreeTraverser(BaseServer* s, boost::asio::io_service& io, const ServerEnvironment& serverEnv); + NodeTreeTraverser(BaseServer* s, boost::asio::io_context& io, const ServerEnvironment& serverEnv); // Disable copy (and move) semantics NodeTreeTraverser(const NodeTreeTraverser&) = delete; const NodeTreeTraverser& operator=(const NodeTreeTraverser&) = delete; diff --git a/libs/server/src/ecflow/server/PeriodicScheduler.hpp b/libs/server/src/ecflow/server/PeriodicScheduler.hpp index cd23e5f8c..568f73298 100644 --- a/libs/server/src/ecflow/server/PeriodicScheduler.hpp +++ b/libs/server/src/ecflow/server/PeriodicScheduler.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include "ecflow/core/Log.hpp" @@ -23,7 +24,7 @@ namespace ecf { class Timer { public: - explicit Timer(boost::asio::io_service& io) : io_service_{io}, timer_{io_service_, boost::posix_time::seconds(0)} {} + explicit Timer(boost::asio::io_context& io) : io_{io}, timer_{io_, boost::posix_time::seconds(0)} {} Timer(const Timer&) = delete; Timer& operator=(const Timer&) = delete; @@ -35,11 +36,11 @@ class Timer { /// Appears that `expires_from_now` is more accurate `then expires_at` /// i.e. timer_.expires_at( timer_.expires_at() + boost::posix_time::seconds( poll_at ) ); timer_.expires_from_now(boost::posix_time::seconds(expiry.count())); - timer_.async_wait(io_service_.wrap(callback)); + timer_.async_wait(boost::asio::bind_executor(io_, callback)); } private: - boost::asio::io_service& io_service_; + boost::asio::io_context& io_; boost::asio::deadline_timer timer_; }; @@ -75,7 +76,7 @@ class PeriodicScheduler { public: PeriodicScheduler(const PeriodicScheduler&) = delete; - PeriodicScheduler(boost::asio::io_service& io, std::chrono::seconds interval, TASK& activity) + PeriodicScheduler(boost::asio::io_context& io, std::chrono::seconds interval, TASK& activity) : timer_(io), last_execution_(), next_execution_(), diff --git a/libs/server/src/ecflow/server/Server.cpp b/libs/server/src/ecflow/server/Server.cpp index 256253858..8572240d6 100644 --- a/libs/server/src/ecflow/server/Server.cpp +++ b/libs/server/src/ecflow/server/Server.cpp @@ -10,7 +10,7 @@ #include "ecflow/server/Server.hpp" -Server::Server(boost::asio::io_service& io_service, ServerEnvironment& serverEnv) - : BaseServer(io_service, serverEnv), - tcp_server_(this, io_service, serverEnv) { +Server::Server(boost::asio::io_context& io, ServerEnvironment& serverEnv) + : BaseServer(io, serverEnv), + tcp_server_(this, io, serverEnv) { } diff --git a/libs/server/src/ecflow/server/Server.hpp b/libs/server/src/ecflow/server/Server.hpp index ea644aa38..5adda9fdc 100644 --- a/libs/server/src/ecflow/server/Server.hpp +++ b/libs/server/src/ecflow/server/Server.hpp @@ -17,7 +17,7 @@ class Server : public BaseServer { public: /// Constructor opens the acceptor and starts waiting for the first incoming connection. - explicit Server(boost::asio::io_service& io_service, ServerEnvironment&); + explicit Server(boost::asio::io_context& io, ServerEnvironment&); ~Server() override = default; private: diff --git a/libs/server/src/ecflow/server/ServerMain.cpp b/libs/server/src/ecflow/server/ServerMain.cpp index b6b90d5ec..90137688e 100644 --- a/libs/server/src/ecflow/server/ServerMain.cpp +++ b/libs/server/src/ecflow/server/ServerMain.cpp @@ -22,15 +22,15 @@ using namespace std; /// \brief The Server entrypoint /// -int run_server(boost::asio::io_service& io_service, const ServerEnvironment& server_environment) { +int run_server(boost::asio::io_context& io, const ServerEnvironment& server_environment) { for (;;) { try { /// Start the server - /// The io_service::run() call will block until all asynchronous operations + /// The io_context::run() call will block until all asynchronous operations /// have finished. While the server is running, there is always at least one /// asynchronous operation outstanding: the asynchronous accept call waiting /// for new incoming connections. - io_service.run(); + io.run(); if (server_environment.debug()) cout << "Normal exit from server\n"; break; @@ -69,19 +69,19 @@ int main(int argc, char* argv[]) { cout << "Server started: ------------------------------------------------>port:" << server_environment.port() << endl; - boost::asio::io_service io_service; + boost::asio::io_context io; #ifdef ECF_OPENSSL if (server_environment.ssl()) { - SslServer theServer(io_service, server_environment); // This can throw exception, bind address in use. - return run_server(io_service, server_environment); + SslServer theServer(io, server_environment); // This can throw exception, bind address in use. + return run_server(io, server_environment); } else { - Server theServer(io_service, server_environment); // This can throw exception, bind address in use. - return run_server(io_service, server_environment); + Server theServer(io, server_environment); // This can throw exception, bind address in use. + return run_server(io, server_environment); } #else - Server theServer(io_service, server_environment); // This can throw exception, bind address in use. - return run_server(io_service, server_environment); + Server theServer(io, server_environment); // This can throw exception, bind address in use. + return run_server(io, server_environment); #endif } catch (ServerEnvironmentException& e) { diff --git a/libs/server/src/ecflow/server/SslServer.cpp b/libs/server/src/ecflow/server/SslServer.cpp index 669597681..765bde167 100644 --- a/libs/server/src/ecflow/server/SslServer.cpp +++ b/libs/server/src/ecflow/server/SslServer.cpp @@ -12,9 +12,9 @@ #include "ecflow/server/ServerEnvironment.hpp" -SslServer::SslServer(boost::asio::io_service& io_service, ServerEnvironment& serverEnv) - : BaseServer(io_service, serverEnv), - server_(this, io_service, serverEnv) { +SslServer::SslServer(boost::asio::io_context& io, ServerEnvironment& serverEnv) + : BaseServer(io, serverEnv), + server_(this, io, serverEnv) { } const std::string& SslServer::ssl() const { diff --git a/libs/server/src/ecflow/server/SslServer.hpp b/libs/server/src/ecflow/server/SslServer.hpp index e51fc77f7..372d10cd3 100644 --- a/libs/server/src/ecflow/server/SslServer.hpp +++ b/libs/server/src/ecflow/server/SslServer.hpp @@ -17,7 +17,7 @@ class SslServer : public BaseServer { public: /// Constructor opens the acceptor and starts waiting for the first incoming connection. - explicit SslServer(boost::asio::io_service& io_service, ServerEnvironment&); + explicit SslServer(boost::asio::io_context& io, ServerEnvironment&); ~SslServer() override = default; private: diff --git a/libs/server/src/ecflow/server/SslTcpServer.cpp b/libs/server/src/ecflow/server/SslTcpServer.cpp index d59be1f6f..41924f4ac 100644 --- a/libs/server/src/ecflow/server/SslTcpServer.cpp +++ b/libs/server/src/ecflow/server/SslTcpServer.cpp @@ -20,8 +20,8 @@ using boost::asio::ip::tcp; using namespace std; using namespace ecf; -SslTcpServer::SslTcpServer(SslServer* server, boost::asio::io_service& io_service, ServerEnvironment& serverEnv) - : TcpBaseServer(server, io_service, serverEnv) { +SslTcpServer::SslTcpServer(SslServer* server, boost::asio::io_context& io, ServerEnvironment& serverEnv) + : TcpBaseServer(server, io, serverEnv) { server_->stats().ECF_SSL_ = serverEnv.openssl().info(); serverEnv.openssl().init_for_server(); @@ -34,7 +34,7 @@ void SslTcpServer::start_accept() { cout << " SslTcpServer::start_accept()" << endl; ssl_connection_ptr new_conn = - std::make_shared(boost::ref(io_service_), boost::ref(serverEnv_.openssl().context())); + std::make_shared(boost::ref(io_), boost::ref(serverEnv_.openssl().context())); acceptor_.async_accept(new_conn->socket_ll(), [this, new_conn](const boost::system::error_code& e) { handle_accept(e, new_conn); }); diff --git a/libs/server/src/ecflow/server/SslTcpServer.hpp b/libs/server/src/ecflow/server/SslTcpServer.hpp index e6812cd60..314d2a7ba 100644 --- a/libs/server/src/ecflow/server/SslTcpServer.hpp +++ b/libs/server/src/ecflow/server/SslTcpServer.hpp @@ -18,7 +18,7 @@ class SslServer; class SslTcpServer : public TcpBaseServer { public: /// Constructor opens the acceptor and starts waiting for the first incoming connection. - explicit SslTcpServer(SslServer*, boost::asio::io_service& io_service, ServerEnvironment&); + explicit SslTcpServer(SslServer*, boost::asio::io_context& io, ServerEnvironment&); ~SslTcpServer() = default; private: diff --git a/libs/server/src/ecflow/server/TcpBaseServer.cpp b/libs/server/src/ecflow/server/TcpBaseServer.cpp index 20028d6e8..c2ef76fcf 100644 --- a/libs/server/src/ecflow/server/TcpBaseServer.cpp +++ b/libs/server/src/ecflow/server/TcpBaseServer.cpp @@ -57,11 +57,11 @@ using boost::asio::ip::tcp; using namespace std; using namespace ecf; -TcpBaseServer::TcpBaseServer(BaseServer* server, boost::asio::io_service& io_service, ServerEnvironment& serverEnv) +TcpBaseServer::TcpBaseServer(BaseServer* server, boost::asio::io_context& io, ServerEnvironment& serverEnv) : server_(server), - io_service_(io_service), + io_(io), serverEnv_(serverEnv), - acceptor_(io_service) { + acceptor_(io) { // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). boost::asio::ip::tcp::endpoint endpoint(serverEnv.tcp_protocol(), serverEnv.port()); acceptor_.open(endpoint.protocol()); @@ -130,12 +130,12 @@ void TcpBaseServer::handle_terminate_request() { void TcpBaseServer::terminate() { // The server is terminated by cancelling all outstanding asynchronous - // operations. Once all operations have finished the io_service::run() call will exit. + // operations. Once all operations have finished the io_context::run() call will exit. if (serverEnv_.debug()) cout << " Server::terminate(): posting call to Server::handle_terminate" << endl; // Post a call to the stop function so that Server::stop() is safe to call from any thread. - io_service_.post([this]() { handle_terminate(); }); + io_.post([this]() { handle_terminate(); }); } void TcpBaseServer::handle_terminate() { @@ -148,6 +148,6 @@ void TcpBaseServer::handle_terminate() { acceptor_.close(); - // Stop the io_service object's event processing loop. Will cause run to return immediately - io_service_.stop(); + // Stop the io_context object's event processing loop. Will cause run to return immediately + io_.stop(); } diff --git a/libs/server/src/ecflow/server/TcpBaseServer.hpp b/libs/server/src/ecflow/server/TcpBaseServer.hpp index 544fda8fd..71254e984 100644 --- a/libs/server/src/ecflow/server/TcpBaseServer.hpp +++ b/libs/server/src/ecflow/server/TcpBaseServer.hpp @@ -23,7 +23,7 @@ class ServerEnvironment; class TcpBaseServer { public: /// Constructor opens the acceptor and starts waiting for the first incoming connection. - explicit TcpBaseServer(BaseServer*, boost::asio::io_service& io_service, ServerEnvironment&); + explicit TcpBaseServer(BaseServer*, boost::asio::io_context& io, ServerEnvironment&); ~TcpBaseServer() = default; void handle_request(); @@ -60,7 +60,7 @@ class TcpBaseServer { protected: BaseServer* server_; - boost::asio::io_service& io_service_; + boost::asio::io_context& io_; ServerEnvironment& serverEnv_; /// The acceptor object used to accept incoming socket connections. diff --git a/libs/server/src/ecflow/server/TcpServer.cpp b/libs/server/src/ecflow/server/TcpServer.cpp index a7e892481..996389f60 100644 --- a/libs/server/src/ecflow/server/TcpServer.cpp +++ b/libs/server/src/ecflow/server/TcpServer.cpp @@ -21,8 +21,8 @@ using boost::asio::ip::tcp; using namespace std; using namespace ecf; -TcpServer::TcpServer(Server* server, boost::asio::io_service& io_service, ServerEnvironment& serverEnv) - : TcpBaseServer(server, io_service, serverEnv) { +TcpServer::TcpServer(Server* server, boost::asio::io_context& io, ServerEnvironment& serverEnv) + : TcpBaseServer(server, io, serverEnv) { // timer_.stop(); // for timing of commands. start_accept(); @@ -31,7 +31,7 @@ TcpServer::TcpServer(Server* server, boost::asio::io_service& io_service, Server void TcpServer::start_accept() { if (serverEnv_.debug()) cout << " TcpServer::start_accept()" << endl; - connection_ptr new_conn = std::make_shared(boost::ref(io_service_)); + connection_ptr new_conn = std::make_shared(boost::ref(io_)); acceptor_.async_accept(new_conn->socket_ll(), [this, new_conn](const boost::system::error_code& e) { handle_accept(e, new_conn); }); } diff --git a/libs/server/src/ecflow/server/TcpServer.hpp b/libs/server/src/ecflow/server/TcpServer.hpp index 8932c0550..2ff2699e0 100644 --- a/libs/server/src/ecflow/server/TcpServer.hpp +++ b/libs/server/src/ecflow/server/TcpServer.hpp @@ -18,7 +18,7 @@ class Server; class TcpServer : public TcpBaseServer { public: /// Constructor opens the acceptor and starts waiting for the first incoming connection. - explicit TcpServer(Server*, boost::asio::io_service& io_service, ServerEnvironment&); + explicit TcpServer(Server*, boost::asio::io_context& io, ServerEnvironment&); ~TcpServer() = default; private: diff --git a/libs/server/test/TestPeriodicScheduler.cpp b/libs/server/test/TestPeriodicScheduler.cpp index e9cb492e6..02048f2ea 100644 --- a/libs/server/test/TestPeriodicScheduler.cpp +++ b/libs/server/test/TestPeriodicScheduler.cpp @@ -76,16 +76,16 @@ struct LongLasting BOOST_AUTO_TEST_CASE(test_periodic_scheduler_over_one_minute) { // Setup time collector Collector collector; - boost::asio::io_service io_service; - ecf::PeriodicScheduler scheduler(io_service, std::chrono::seconds(30), collector); + boost::asio::io_context io; + ecf::PeriodicScheduler scheduler(io, std::chrono::seconds(30), collector); scheduler.start(); // Arrange time collector termination - ecf::Timer teardown(io_service); + ecf::Timer teardown(io); teardown.set([&scheduler](const boost::system::error_code& error) { scheduler.terminate(); }, std::chrono::seconds(62)); // Run services - io_service.run(); + io.run(); BOOST_CHECK_EQUAL(collector.instants.size(), static_cast(62)); } @@ -93,16 +93,16 @@ BOOST_AUTO_TEST_CASE(test_periodic_scheduler_over_one_minute) { BOOST_AUTO_TEST_CASE(test_periodic_scheduler_with_long_lasting_activity) { // Setup time collector LongLasting activity{std::chrono::milliseconds(2499)}; - boost::asio::io_service io_service; - ecf::PeriodicScheduler scheduler(io_service, std::chrono::seconds(10), activity); + boost::asio::io_context io; + ecf::PeriodicScheduler scheduler(io, std::chrono::seconds(10), activity); scheduler.start(); // Arrange time collector termination - ecf::Timer teardown(io_service); + ecf::Timer teardown(io); teardown.set([&scheduler](const boost::system::error_code& error) { scheduler.terminate(); }, std::chrono::seconds(60)); // Run services - io_service.run(); + io.run(); } BOOST_AUTO_TEST_SUITE_END() diff --git a/libs/server/test/TestServer.cpp b/libs/server/test/TestServer.cpp index 575c2617c..21d57ffe2 100644 --- a/libs/server/test/TestServer.cpp +++ b/libs/server/test/TestServer.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_SUITE(T_Server) // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ class TestServer : public Server { public: - explicit TestServer(boost::asio::io_service& io_service, ServerEnvironment& s) : Server(io_service, s) {} + explicit TestServer(boost::asio::io_context& io, ServerEnvironment& s) : Server(io, s) {} ~TestServer() override = default; // abort server if check pt files exist, but can't be loaded @@ -107,8 +107,8 @@ void test_the_server(const std::string& port) { BOOST_CHECK_MESSAGE(server_environment.valid(errorMsg), errorMsg); { - boost::asio::io_service io_service; - TestServer theServer(io_service, server_environment); // This can throw exception, bind address in use. + boost::asio::io_context io; + TestServer theServer(io, server_environment); // This can throw exception, bind address in use. BOOST_REQUIRE_MESSAGE(theServer.defs(), "Expected defs to be created"); diff --git a/libs/udp/src/ecflow/udp/UDPClient.hpp b/libs/udp/src/ecflow/udp/UDPClient.hpp index f24426a97..dac9d6737 100644 --- a/libs/udp/src/ecflow/udp/UDPClient.hpp +++ b/libs/udp/src/ecflow/udp/UDPClient.hpp @@ -24,10 +24,10 @@ namespace internal_detail { */ class BaseUDPConnection { public: - BaseUDPConnection(boost::asio::io_service& io_service, + BaseUDPConnection(boost::asio::io_context& io, boost::asio::ip::udp::endpoint server_endpoint, const std::string& request) - : socket_(io_service), + : socket_(io), server_endpoint_(std::move(server_endpoint)) { // Open socket connection socket_.open(boost::asio::ip::udp::v4()); @@ -74,13 +74,13 @@ class BaseUDPClient { BaseUDPClient(hostname_t host, port_t port) : host_{std::move(host)}, port_{std::move(port)} {} void send(const data_t& data) { - boost::asio::io_service io_service; - boost::asio::ip::udp::resolver resolver(io_service); + boost::asio::io_context io; + boost::asio::ip::udp::resolver resolver(io); boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), host_, port_); boost::asio::ip::udp::endpoint server_endpoint = *resolver.resolve(query); - internal_detail::BaseUDPConnection connection(io_service, server_endpoint, data); - io_service.run(); + internal_detail::BaseUDPConnection connection(io, server_endpoint, data); + io.run(); } private: diff --git a/libs/udp/src/ecflow/udp/UDPServer.hpp b/libs/udp/src/ecflow/udp/UDPServer.hpp index 04af4a0fb..19a0a03e0 100644 --- a/libs/udp/src/ecflow/udp/UDPServer.hpp +++ b/libs/udp/src/ecflow/udp/UDPServer.hpp @@ -25,10 +25,10 @@ template class BaseUdpServerConnection { public: BaseUdpServerConnection(HANDLER handler, - boost::asio::io_service& io_service, + boost::asio::io_context& io, const boost::asio::ip::udp::endpoint& server_endpoint) : handler_{std::move(handler)}, - socket_(io_service, server_endpoint), + socket_(io, server_endpoint), client_endpoint_{}, buffer_{} { start(); @@ -78,16 +78,16 @@ template class BaseUdpServer { public: BaseUdpServer(HANDLER handler, uint16_t port) - : io_service_{}, + : io_{}, server_endpoint_{boost::asio::ip::udp::v4(), port}, - connection_{handler, io_service_, server_endpoint_} {} + connection_{handler, io_, server_endpoint_} {} BaseUdpServer(const BaseUdpServer&) = delete; BaseUdpServer(BaseUdpServer&&) = delete; - void run() { io_service_.run(); } + void run() { io_.run(); } private: - boost::asio::io_service io_service_; + boost::asio::io_context io_; boost::asio::ip::udp::endpoint server_endpoint_; internal_detail::BaseUdpServerConnection connection_; };