Fix for boost 1.87 Removed the diff for the msbuild project files, didn't apply cleanly and not relevant anyway. This will merged in the next stable of domoticz. Pullrequest: https://github.com/domoticz/domoticz/pull/6252 Patch: https://patch-diff.githubusercontent.com/raw/domoticz/domoticz/pull/6252.patch-diff diff --git hardware/ASyncSerial.cpp hardware/ASyncSerial.cpp index 52c950d..6147cdb 100644 --- hardware/ASyncSerial.cpp +++ hardware/ASyncSerial.cpp @@ -54,7 +54,7 @@ public: { } - boost::asio::io_service io; ///< Io service object + boost::asio::io_context io; ///< Io service object boost::asio::serial_port port; ///< Serial port object boost::thread backgroundThread; ///< Thread that runs read/write operations bool open{ false }; ///< True if port open @@ -117,10 +117,10 @@ void AsyncSerial::open(const std::string& devname, unsigned int baud_rate, throw; } - pimpl->io.reset(); + pimpl->io.restart(); - // This gives some work to the io_service before it is started - pimpl->io.post([this] { return doRead(); }); + // This gives some work to the io_context before it is started + boost::asio::post(pimpl->io, [this] { return doRead(); }); boost::thread t([p = &pimpl->io] { p->run(); }); pimpl->backgroundThread.swap(t); @@ -149,10 +149,10 @@ void AsyncSerial::openOnlyBaud(const std::string& devname, unsigned int baud_rat throw; } - pimpl->io.reset(); + pimpl->io.restart(); - //This gives some work to the io_service before it is started - pimpl->io.post([this] { return doRead(); }); + //This gives some work to the io_context before it is started + boost::asio::post(pimpl->io, [this] { return doRead(); }); boost::thread t([p = &pimpl->io] { p->run(); }); pimpl->backgroundThread.swap(t); @@ -176,9 +176,9 @@ void AsyncSerial::close() if(!isOpen()) return; pimpl->open = false; - pimpl->io.post([this] { doClose(); }); + boost::asio::post(pimpl->io, [this] { doClose(); }); pimpl->backgroundThread.join(); - pimpl->io.reset(); + pimpl->io.restart(); if(errorStatus()) { throw(boost::system::system_error(boost::system::error_code(), @@ -192,7 +192,7 @@ void AsyncSerial::write(const char *data, size_t size) std::lock_guard l(pimpl->writeQueueMutex); pimpl->writeQueue.insert(pimpl->writeQueue.end(),data,data+size); } - pimpl->io.post([this] { doWrite(); }); + boost::asio::post(pimpl->io, [this] { doWrite(); }); } void AsyncSerial::write(const std::string &data) @@ -201,7 +201,7 @@ void AsyncSerial::write(const std::string &data) std::lock_guard l(pimpl->writeQueueMutex); pimpl->writeQueue.insert(pimpl->writeQueue.end(), data.c_str(), data.c_str()+data.size()); } - pimpl->io.post([this] { doWrite(); }); + boost::asio::post(pimpl->io, [this] { doWrite(); }); } void AsyncSerial::write(const std::vector& data) @@ -211,7 +211,7 @@ void AsyncSerial::write(const std::vector& data) pimpl->writeQueue.insert(pimpl->writeQueue.end(),data.begin(), data.end()); } - pimpl->io.post([this] { doWrite(); }); + boost::asio::post(pimpl->io, [this] { doWrite(); }); } void AsyncSerial::writeString(const std::string& s) @@ -220,7 +220,7 @@ void AsyncSerial::writeString(const std::string& s) std::lock_guard l(pimpl->writeQueueMutex); pimpl->writeQueue.insert(pimpl->writeQueue.end(),s.begin(),s.end()); } - pimpl->io.post([this] { doWrite(); }); + boost::asio::post(pimpl->io, [this] { doWrite(); }); } void AsyncSerial::doRead() diff --git hardware/ASyncSerial.h hardware/ASyncSerial.h index 0a51ef0..de83f8a 100644 --- hardware/ASyncSerial.h +++ hardware/ASyncSerial.h @@ -123,27 +123,27 @@ class AsyncSerial : private domoticz::noncopyable /** * Callback called to start an asynchronous read operation. - * This callback is called by the io_service in the spawned thread. + * This callback is called by the io_context in the spawned thread. */ void doRead(); /** * Callback called at the end of the asynchronous operation. - * This callback is called by the io_service in the spawned thread. + * This callback is called by the io_context in the spawned thread. */ void readEnd(const boost::system::error_code &error, size_t bytes_transferred); /** * Callback called to start an asynchronous write operation. * If it is already in progress, does nothing. - * This callback is called by the io_service in the spawned thread. + * This callback is called by the io_context in the spawned thread. */ void doWrite(); /** * Callback called at the end of an asynchronuous write operation, * if there is more data to write, restarts a new write operation. - * This callback is called by the io_service in the spawned thread. + * This callback is called by the io_context in the spawned thread. */ void writeEnd(const boost::system::error_code &error); diff --git hardware/ASyncTCP.cpp hardware/ASyncTCP.cpp index a375561..7c3b536 100644 --- hardware/ASyncTCP.cpp +++ hardware/ASyncTCP.cpp @@ -4,213 +4,241 @@ #include // for error_code #include "../main/Logger.h" -struct hostent; - #define MAX_TCP_BUFFER_SIZE 4096 -#ifndef WIN32 - #include //gethostbyname -#endif - #define STATUS_OK(err) !err - -ASyncTCP::ASyncTCP(const bool secure) +#define STATUS_ERR(err) err + +ASyncTCP::ASyncTCP(const bool secure) : + m_Tcpwork(boost::asio::make_work_guard(m_io_context)) + , m_Socket(m_io_context) + , m_Resolver(m_io_context) + , m_ReconnectTimer(m_io_context) + , m_TimeoutTimer(m_io_context) + , m_SendStrand(m_io_context) #ifdef WWW_ENABLE_SSL - : mSecure(secure) + , m_bSecure(secure) #endif { m_pRXBuffer = new uint8_t[MAX_TCP_BUFFER_SIZE]; #ifdef WWW_ENABLE_SSL mContext.set_verify_mode(boost::asio::ssl::verify_none); - if (mSecure) + if (m_bSecure) { - mSslSocket.reset(new boost::asio::ssl::stream(mIos, mContext)); + m_SslSocket.reset(new boost::asio::ssl::stream(m_io_context, mContext)); } #endif } ASyncTCP::~ASyncTCP() { - assert(mTcpthread == nullptr); - mIsTerminating = true; - if (mTcpthread) + assert(m_Tcpthread == nullptr); + m_bIsTerminating = true; + if (m_Tcpthread) { //This should never happen. terminate() never called!! - _log.Log(LOG_ERROR, "ASyncTCP: Workerthread not closed. terminate() never called!!!"); - mIos.stop(); - if (mTcpthread) + _log.Log(LOG_ERROR, "ASyncTCP: Worker thread not closed. terminate() never called!!!"); + m_io_context.stop(); + if (m_Tcpthread) { - mTcpthread->join(); - mTcpthread.reset(); + m_Tcpthread->join(); + m_Tcpthread.reset(); } } if (m_pRXBuffer != nullptr) delete[] m_pRXBuffer; } -void ASyncTCP::SetReconnectDelay(int32_t Delay) +void ASyncTCP::SetReconnectDelay(const int32_t Delay) { - mReconnectDelay = Delay; + m_iReconnectDelay = Delay; } void ASyncTCP::connect(const std::string& ip, uint16_t port) { - assert(!mSocket.is_open()); - if (mSocket.is_open()) + assert(!m_Socket.is_open()); + if (m_Socket.is_open()) { _log.Log(LOG_ERROR, "ASyncTCP: connect called while socket is still open. !!!"); terminate(); } - // RK: We reset mIos here because it might have been stopped in terminate() - mIos.reset(); - // RK: After the reset, we need to provide it work anew - mTcpwork = std::make_shared(mIos); - if (!mTcpthread) - mTcpthread = std::make_shared([p = &mIos] { p->run(); }); - - mIp = ip; - mPort = port; + m_IP = ip; + m_Port = port; std::string port_str = std::to_string(port); - boost::asio::ip::tcp::resolver::query query(ip, port_str); timeout_start_timer(); - mResolver.async_resolve(query, [this](auto &&err, auto &&iter) { cb_resolve_done(err, iter); }); + + m_Resolver.async_resolve( + ip, port_str, + [this](const boost::system::error_code& error, const boost::asio::ip::tcp::resolver::results_type& endpoints) { + handle_resolve(error, endpoints); + } + ); + + // RK: We restart m_io_context here because it might have been stopped in terminate() + m_io_context.restart(); + // RK: After the reset, we need to provide it work anew + m_Tcpwork.reset(); + m_Tcpwork.emplace(boost::asio::make_work_guard(m_io_context)); + if (!m_Tcpthread) + m_Tcpthread = std::make_shared([p = &m_io_context] { p->run(); }); } -void ASyncTCP::cb_resolve_done(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) +void ASyncTCP::handle_resolve(const boost::system::error_code& error, const boost::asio::ip::tcp::resolver::results_type &endpoints) { - if (mIsTerminating) return; + if (m_bIsTerminating) return; - if (STATUS_OK(error)) - { - connect_start(endpoint_iterator); - } - else + if (STATUS_ERR(error)) { process_error(error); + return; } -} - -void ASyncTCP::connect_start(boost::asio::ip::tcp::resolver::iterator& endpoint_iterator) -{ - if (mIsConnected) return; - - mEndPoint = *endpoint_iterator++; + if (m_bIsConnected) return; timeout_start_timer(); + #ifdef WWW_ENABLE_SSL - if (mSecure) + if (m_bSecure) { // we reset the ssl socket, because the ssl context needs to be reinitialized after a reconnect - mSslSocket.reset(new boost::asio::ssl::stream(mIos, mContext)); - mSslSocket->lowest_layer().async_connect(mEndPoint, [this, endpoint_iterator](auto &&err) mutable { cb_connect_done(err, endpoint_iterator); }); + m_SslSocket.reset(new boost::asio::ssl::stream(m_io_context, mContext)); + boost::asio::async_connect(m_SslSocket->lowest_layer(), endpoints, + [this](const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint) + { + handle_connect(error, endpoint); + } + ); } else #endif { - mSocket.async_connect(mEndPoint, [this, endpoint_iterator](auto &&err) mutable { cb_connect_done(err, endpoint_iterator); }); + boost::asio::async_connect(m_Socket, endpoints, + [this](const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint) + { + handle_connect(error, endpoint); + } + ); } } -void ASyncTCP::cb_connect_done(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) +void ASyncTCP::handle_connect(const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& /*endpoint*/) { - if (mIsTerminating) return; + if (m_bIsTerminating) return; - if (STATUS_OK(error)) + if (STATUS_ERR(error)) { + process_error(error); + return; + } #ifdef WWW_ENABLE_SSL - if (mSecure) - { - timeout_start_timer(); - mSslSocket->async_handshake(boost::asio::ssl::stream_base::client, [this](auto &&err) { cb_handshake_done(err); }); - } - else -#endif - { - process_connection(); - } + if (m_bSecure) + { + timeout_start_timer(); + m_SslSocket->async_handshake(boost::asio::ssl::stream_base::client, + [this](const boost::system::error_code& error) { + cb_handshake_done(error); + } + ); } - else + else +#endif { - if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) - { - // The connection failed. Try the next endpoint in the list. - connect_start(endpoint_iterator); - return; - } - process_error(error); + process_connection(); } } #ifdef WWW_ENABLE_SSL void ASyncTCP::cb_handshake_done(const boost::system::error_code& error) { - if (mIsTerminating) return; + if (m_bIsTerminating) return; - if (STATUS_OK(error)) - { - process_connection(); - } - else + if (STATUS_ERR(error)) { process_error(error); + return; } + process_connection(); +#endif } + +void ASyncTCP::process_connection() +{ + m_bIsConnected = true; +#ifdef WWW_ENABLE_SSL + + if (!m_bSecure) #endif + { + // RK: only if non-secure + boost::asio::socket_base::keep_alive option(true); + m_Socket.set_option(option); + } + OnConnect(); + do_read_start(); + do_write_start(); +} void ASyncTCP::reconnect_start_timer() { - if (mIsReconnecting) return; + if (m_bIsReconnecting) return; - if (mReconnectDelay != 0) + if (m_iReconnectDelay != 0) { - mIsReconnecting = true; - - mReconnectTimer.expires_from_now(boost::posix_time::seconds(mReconnectDelay)); - mReconnectTimer.async_wait([this](auto &&err) { cb_reconnect_start(err); }); + m_bIsReconnecting = true; + + m_ReconnectTimer.expires_from_now(boost::posix_time::seconds(m_iReconnectDelay)); + m_ReconnectTimer.async_wait( + [this](const boost::system::error_code& error) { + cb_reconnect_start(error); + } + ); } } void ASyncTCP::cb_reconnect_start(const boost::system::error_code& error) { - mIsReconnecting = false; - mReconnectTimer.cancel(); - mTimeoutTimer.cancel(); + m_bIsReconnecting = false; + m_ReconnectTimer.cancel(); + m_TimeoutTimer.cancel(); - if (mIsConnected) return; + if (m_bIsConnected) return; if (error) return; // timer was cancelled do_close(); - connect(mIp, mPort); + connect(m_IP, m_Port); } void ASyncTCP::terminate(const bool silent) { - mIsTerminating = true; + m_bIsTerminating = true; disconnect(silent); - mTcpwork.reset(); - mIos.stop(); - if (mTcpthread) + m_Tcpwork.reset(); + m_io_context.stop(); + if (m_Tcpthread) { - mTcpthread->join(); - mTcpthread.reset(); + m_Tcpthread->join(); + m_Tcpthread.reset(); } - mIsReconnecting = false; - mIsConnected = false; - mWriteQ.clear(); - mIsTerminating = false; + m_bIsReconnecting = false; + m_bIsConnected = false; + m_WriteQ.clear(); + m_bIsTerminating = false; } void ASyncTCP::disconnect(const bool silent) { - mReconnectTimer.cancel(); - mTimeoutTimer.cancel(); - if (!mTcpthread) return; + m_ReconnectTimer.cancel(); + m_TimeoutTimer.cancel(); + if (!m_Tcpthread) return; try { - mIos.post([this] { do_close(); }); + boost::asio::post(m_io_context, + [this] { + do_close(); + } + ); } catch (...) { @@ -223,62 +251,68 @@ void ASyncTCP::disconnect(const bool silent) void ASyncTCP::do_close() { - if (mIsReconnecting) { + if (m_bIsReconnecting) { return; } - mReconnectTimer.cancel(); - mTimeoutTimer.cancel(); + m_ReconnectTimer.cancel(); + m_TimeoutTimer.cancel(); boost::system::error_code ec; #ifdef WWW_ENABLE_SSL - if (mSecure) + if (m_bSecure) { - if (mSslSocket->lowest_layer().is_open()) + if (m_SslSocket->lowest_layer().is_open()) { - mSslSocket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); - mSslSocket->lowest_layer().close(ec); + m_SslSocket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + m_SslSocket->lowest_layer().close(ec); } } else #endif { - if (mSocket.is_open()) + if (m_Socket.is_open()) { - mSocket.close(ec); + m_Socket.close(ec); } } } void ASyncTCP::do_read_start() { - if (mIsTerminating) return; - if (!mIsConnected) return; + if (m_bIsTerminating) return; + if (!m_bIsConnected) return; timeout_start_timer(); #ifdef WWW_ENABLE_SSL - if (mSecure) + if (m_bSecure) { - mSslSocket->async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), [this](auto &&err, auto bytes) { cb_read_done(err, bytes); }); + m_SslSocket->async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), + [this](const boost::system::error_code& error, size_t bytes_transferred) { + cb_read_done(error, bytes_transferred); + } + ); } else #endif { - mSocket.async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), [this](auto &&err, auto bytes) { cb_read_done(err, bytes); }); + m_Socket.async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), + [this](const boost::system::error_code& error, size_t bytes_transferred) { + cb_read_done(error, bytes_transferred); + } + ); } } void ASyncTCP::cb_read_done(const boost::system::error_code& error, size_t bytes_transferred) { - if (mIsTerminating) return; + if (m_bIsTerminating) return; - if (STATUS_OK(error)) - { - OnData(m_pRXBuffer, bytes_transferred); - do_read_start(); - } - else + if (STATUS_ERR(error)) { process_error(error); + return; } + OnData(m_pRXBuffer, bytes_transferred); + do_read_start(); } void ASyncTCP::write(const uint8_t* pData, size_t length) @@ -288,77 +322,66 @@ void ASyncTCP::write(const uint8_t* pData, size_t length) void ASyncTCP::write(const std::string& msg) { - if (!mTcpthread) return; + if (!m_Tcpthread) return; - mSendStrand.post([this, msg]() { cb_write_queue(msg); }); + boost::asio::post(m_SendStrand, [this, msg]() { cb_write_queue(msg); }); } void ASyncTCP::cb_write_queue(const std::string& msg) { - mWriteQ.push_back(msg); + m_WriteQ.push_back(msg); - if (mWriteQ.size() == 1) + if (m_WriteQ.size() == 1) do_write_start(); } void ASyncTCP::do_write_start() { - if (mIsTerminating) return; - if (!mIsConnected) return; - if (mWriteQ.empty()) + if (m_bIsTerminating) return; + if (!m_bIsConnected) return; + if (m_WriteQ.empty()) return; timeout_start_timer(); #ifdef WWW_ENABLE_SSL - if (mSecure) + if (m_bSecure) { - boost::asio::async_write(*mSslSocket, boost::asio::buffer(mWriteQ.front()), [this](auto &&err, auto) { cb_write_done(err); }); + boost::asio::async_write(*m_SslSocket, boost::asio::buffer(m_WriteQ.front()), + [this](const boost::system::error_code& error, std::size_t length) { + cb_write_done(error, length); + } + ); } else #endif { - boost::asio::async_write(mSocket, boost::asio::buffer(mWriteQ.front()), [this](auto &&err, auto) { cb_write_done(err); }); + boost::asio::async_write(m_Socket, boost::asio::buffer(m_WriteQ.front()), + [this](const boost::system::error_code& error, std::size_t length) { + cb_write_done(error, length); + } + ); } } -void ASyncTCP::cb_write_done(const boost::system::error_code& error) +void ASyncTCP::cb_write_done(const boost::system::error_code& error, std::size_t /*length*/) { - if (mIsTerminating) return; + if (m_bIsTerminating) return; - if (STATUS_OK(error)) - { - mWriteQ.pop_front(); - do_write_start(); - } - else + if (STATUS_ERR(error)) { process_error(error); + return; } -} - -void ASyncTCP::process_connection() -{ - mIsConnected = true; -#ifdef WWW_ENABLE_SSL - - if (!mSecure) -#endif - { - // RK: only if non-secure - boost::asio::socket_base::keep_alive option(true); - mSocket.set_option(option); - } - OnConnect(); - do_read_start(); + m_WriteQ.pop_front(); do_write_start(); } void ASyncTCP::process_error(const boost::system::error_code& error) { do_close(); - if (mIsConnected) + if (m_bIsConnected) { - mIsConnected = false; + m_bIsConnected = false; OnDisconnect(); } @@ -369,20 +392,23 @@ void ASyncTCP::process_error(const boost::system::error_code& error) reconnect_start_timer(); } -/* timeout methods */ void ASyncTCP::timeout_start_timer() { - if (0 == mTimeoutDelay) { + if (0 == m_iTimeoutDelay) { return; } timeout_cancel_timer(); - mTimeoutTimer.expires_from_now(boost::posix_time::seconds(mTimeoutDelay)); - mTimeoutTimer.async_wait([this](auto &&err) { timeout_handler(err); }); + m_TimeoutTimer.expires_from_now(boost::posix_time::seconds(m_iTimeoutDelay)); + m_TimeoutTimer.async_wait( + [this](const boost::system::error_code& error) { + timeout_handler(error); + } + ); } void ASyncTCP::timeout_cancel_timer() { - mTimeoutTimer.cancel(); + m_TimeoutTimer.cancel(); } void ASyncTCP::timeout_handler(const boost::system::error_code& error) @@ -397,5 +423,5 @@ void ASyncTCP::timeout_handler(const boost::system::error_code& error) void ASyncTCP::SetTimeout(const uint32_t Timeout) { - mTimeoutDelay = Timeout; + m_iTimeoutDelay = Timeout; } diff --git hardware/ASyncTCP.h hardware/ASyncTCP.h index cf859bb..a8b3ae2 100644 --- hardware/ASyncTCP.h +++ hardware/ASyncTCP.h @@ -3,39 +3,31 @@ #include // for size_t #include // for write queue #include // for deadline_timer -#include // for io_service +#include // for io_context #include // for strand #include // for tcp, tcp::endpoint, tcp::s... #include // for secure sockets #include // for secure sockets #include // for exception +#include // for optional #define ASYNCTCP_THREAD_NAME "ASyncTCP" #define DEFAULT_RECONNECT_TIME 30 #define DEFAULT_TIMEOUT_TIME 60 -namespace boost -{ - namespace system - { - class error_code; - } // namespace system -} // namespace boost - class ASyncTCP { - protected: +protected: ASyncTCP(bool secure = false); virtual ~ASyncTCP(); - - void connect(const std::string &hostname, uint16_t port); + void connect(const std::string& hostname, uint16_t port); void disconnect(bool silent = true); - void write(const std::string &msg); - void write(const uint8_t *pData, size_t length); - void SetReconnectDelay(int32_t Delay = DEFAULT_RECONNECT_TIME); + void write(const std::string& msg); + void write(const uint8_t* pData, size_t length); + void SetReconnectDelay(const int32_t Delay = DEFAULT_RECONNECT_TIME); bool isConnected() { - return mIsConnected; + return m_bIsConnected; }; void terminate(bool silent = true); void SetTimeout(uint32_t Timeout = DEFAULT_TIMEOUT_TIME); @@ -43,65 +35,61 @@ class ASyncTCP // Callback interface to implement in derived classes virtual void OnConnect() = 0; virtual void OnDisconnect() = 0; - virtual void OnData(const uint8_t *pData, size_t length) = 0; - virtual void OnError(const boost::system::error_code &error) = 0; - - boost::asio::io_service mIos; // protected to allow derived classes to attach timers etc. + virtual void OnData(const uint8_t* pData, size_t length) = 0; + virtual void OnError(const boost::system::error_code& error) = 0; - private: - void cb_resolve_done(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator); - void connect_start(boost::asio::ip::tcp::resolver::iterator &endpoint_iterator); - void cb_connect_done(const boost::system::error_code &error, boost::asio::ip::tcp::resolver::iterator &endpoint_iterator); + boost::asio::io_context m_io_context; // protected to allow derived classes to attach timers etc. +private: + void handle_resolve(const boost::system::error_code& ec, const boost::asio::ip::tcp::resolver::results_type &results); + void handle_connect(const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint); #ifdef WWW_ENABLE_SSL - void cb_handshake_done(const boost::system::error_code &error); + void cb_handshake_done(const boost::system::error_code& error); #endif - /* timeout methods */ void timeout_start_timer(); void timeout_cancel_timer(); void reconnect_start_timer(); - void timeout_handler(const boost::system::error_code &error); + void timeout_handler(const boost::system::error_code& error); - void cb_reconnect_start(const boost::system::error_code &error); + void cb_reconnect_start(const boost::system::error_code& error); void do_close(); void do_read_start(); - void cb_read_done(const boost::system::error_code &error, size_t bytes_transferred); + void cb_read_done(const boost::system::error_code& error, size_t bytes_transferred); - void cb_write_queue(const std::string &msg); + void cb_write_queue(const std::string& msg); void do_write_start(); - void cb_write_done(const boost::system::error_code &error); + void cb_write_done(const boost::system::error_code& error, size_t length); void process_connection(); - void process_error(const boost::system::error_code &error); + void process_error(const boost::system::error_code& error); - bool mIsConnected = false; - bool mIsReconnecting = false; - bool mIsTerminating = false; + bool m_bIsConnected = false; + bool m_bIsReconnecting = false; + bool m_bIsTerminating = false; - boost::asio::io_service::strand mSendStrand{ mIos }; - std::deque mWriteQ; // we need a write queue to allow concurrent writes + boost::asio::io_context::strand m_SendStrand; + std::deque m_WriteQ; // we need a write queue to allow concurrent writes uint8_t* m_pRXBuffer = nullptr; - int mReconnectDelay = DEFAULT_RECONNECT_TIME; - int mTimeoutDelay = 0; - boost::asio::deadline_timer mReconnectTimer{ mIos }; - boost::asio::deadline_timer mTimeoutTimer{ mIos }; + int m_iReconnectDelay = DEFAULT_RECONNECT_TIME; + int m_iTimeoutDelay = 0; + boost::asio::deadline_timer m_ReconnectTimer; + boost::asio::deadline_timer m_TimeoutTimer; - std::shared_ptr mTcpthread; - std::shared_ptr mTcpwork; + std::shared_ptr m_Tcpthread; + std::optional> m_Tcpwork; #ifdef WWW_ENABLE_SSL - const bool mSecure; + const bool m_bSecure; boost::asio::ssl::context mContext{ boost::asio::ssl::context::sslv23 }; - std::shared_ptr> mSslSocket; // the ssl socket + std::shared_ptr> m_SslSocket; #endif - boost::asio::ip::tcp::socket mSocket{ mIos }; - boost::asio::ip::tcp::endpoint mEndPoint; - boost::asio::ip::tcp::resolver mResolver{ mIos }; + boost::asio::ip::tcp::socket m_Socket; + boost::asio::ip::tcp::resolver m_Resolver; - std::string mIp; - uint16_t mPort; + std::string m_IP; + uint16_t m_Port; }; diff --git hardware/Arilux.cpp hardware/Arilux.cpp index 400f5a3..20bc373 100644 --- hardware/Arilux.cpp +++ hardware/Arilux.cpp @@ -79,7 +79,7 @@ void Arilux::InsertUpdateSwitch(const std::string &lightName, const int subType, { uint32_t sID; try { - sID = boost::asio::ip::address_v4::from_string(location).to_ulong(); + sID = boost::asio::ip::make_address_v4(location).to_uint(); } catch (const std::exception &e) { Log(LOG_ERROR, "Bad IP address: %s (%s)", location.c_str(), e.what()); return; @@ -112,8 +112,8 @@ bool Arilux::SendTCPCommand(uint32_t ip,std::vector &command) sum = sum & 0xFF; command.push_back((unsigned char)sum); - boost::asio::io_service io_service; - boost::asio::ip::tcp::socket sendSocket(io_service); + boost::asio::io_context io_context; + boost::asio::ip::tcp::socket sendSocket(io_context); boost::asio::ip::address_v4 address(ip); boost::asio::ip::tcp::endpoint endpoint(address, 5577); try diff --git hardware/Kodi.cpp hardware/Kodi.cpp index b528017..5ababf6 100644 --- hardware/Kodi.cpp +++ hardware/Kodi.cpp @@ -143,14 +143,14 @@ _eNotificationTypes CKodiNode::CKodiStatus::NotificationType() } } -CKodiNode::CKodiNode(boost::asio::io_service *pIos, const int pHwdID, const int PollIntervalsec, const int pTimeoutMs, +CKodiNode::CKodiNode(boost::asio::io_context *pIoc, const int pHwdID, const int PollIntervalsec, const int pTimeoutMs, const std::string& pID, const std::string& pName, const std::string& pIP, const std::string& pPort) { m_Busy = false; m_Stoppable = false; m_PlaylistPosition = 0; - m_Ios = pIos; + m_Ioc = pIoc; m_HwdID = pHwdID; m_DevID = atoi(pID.c_str()); sprintf(m_szDevID, "%X%02X%02X%02X", 0, 0, (m_DevID & 0xFF00) >> 8, m_DevID & 0xFF); @@ -581,11 +581,10 @@ void CKodiNode::handleConnect() { m_iMissedPongs = 0; boost::system::error_code ec; - boost::asio::ip::tcp::resolver resolver(*m_Ios); - boost::asio::ip::tcp::resolver::query query(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1))); - auto iter = resolver.resolve(query); - boost::asio::ip::tcp::endpoint endpoint = *iter; - m_Socket = new boost::asio::ip::tcp::socket(*m_Ios); + boost::asio::ip::tcp::resolver resolver(*m_Ioc); + auto iter = resolver.resolve(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1))); + boost::asio::ip::tcp::endpoint endpoint = *iter.begin(); + m_Socket = new boost::asio::ip::tcp::socket(*m_Ioc); m_Socket->connect(endpoint, ec); if (!ec) { @@ -975,19 +974,19 @@ void CKodi::Do_Work() _log.Log(LOG_NORM, "Kodi: (%s) - Restarting thread.", node->m_Name.c_str()); boost::thread *tAsync = new boost::thread(&CKodiNode::Do_Work, node); SetThreadName(tAsync->native_handle(), "KodiNode"); - m_ios.stop(); + m_ioc.stop(); } if (node->IsOn()) bWorkToDo = true; } - if (bWorkToDo && m_ios.stopped()) // make sure that there is a boost thread to service i/o operations + if (bWorkToDo && m_ioc.stopped()) // make sure that there is a boost thread to service i/o operations { - m_ios.reset(); + m_ioc.restart(); // Note that this is the only thread that handles async i/o so we don't // need to worry about locking or concurrency issues when processing messages _log.Log(LOG_NORM, "Kodi: Restarting I/O service thread."); - boost::thread bt([p = &m_ios] { p->run(); }); + boost::thread bt([p = &m_ioc] { p->run(); }); SetThreadName(bt.native_handle(), "KodiIO"); } } @@ -1138,7 +1137,7 @@ void CKodi::ReloadNodes() { UnloadNodes(); - m_ios.reset(); // in case this is not the first time in + m_ioc.restart(); // in case this is not the first time in std::vector > result; result = m_sql.safe_query("SELECT ID,Name,MacAddress,Timeout FROM WOLNodes WHERE (HardwareID==%d)", m_HwdID); @@ -1149,7 +1148,7 @@ void CKodi::ReloadNodes() // create a vector to hold the nodes for (const auto &sd : result) { - auto pNode = std::make_shared(&m_ios, m_HwdID, m_iPollInterval, m_iPingTimeoutms, sd[0], sd[1], sd[2], sd[3]); + auto pNode = std::make_shared(&m_ioc, m_HwdID, m_iPollInterval, m_iPingTimeoutms, sd[0], sd[1], sd[2], sd[3]); m_pNodes.push_back(pNode); } // start the threads to control each kodi @@ -1161,7 +1160,7 @@ void CKodi::ReloadNodes() } sleep_milliseconds(100); _log.Log(LOG_NORM, "Kodi: Starting I/O service thread."); - boost::thread bt([p = &m_ios] { p->run(); }); + boost::thread bt([p = &m_ioc] { p->run(); }); SetThreadName(bt.native_handle(), "KodiIO"); } } @@ -1170,10 +1169,10 @@ void CKodi::UnloadNodes() { std::lock_guard l(m_mutex); - m_ios.stop(); // stop the service if it is running + m_ioc.stop(); // stop the service if it is running sleep_milliseconds(100); - while (((!m_pNodes.empty()) || (!m_ios.stopped()))) + while (((!m_pNodes.empty()) || (!m_ioc.stopped()))) { for (auto itt = m_pNodes.begin(); itt != m_pNodes.end(); ++itt) { diff --git hardware/Kodi.h hardware/Kodi.h index 14f331c..4435740 100644 --- hardware/Kodi.h +++ hardware/Kodi.h @@ -150,7 +150,7 @@ class CKodiNode : public std::enable_shared_from_this, StoppableTask }; public: - CKodiNode(boost::asio::io_service *, int, int, int, const std::string &, const std::string &, const std::string &, const std::string &); + CKodiNode(boost::asio::io_context *, int, int, int, const std::string &, const std::string &, const std::string &, const std::string &); ~CKodiNode(); void Do_Work(); void SendCommand(const std::string &); @@ -207,7 +207,7 @@ class CKodiNode : public std::enable_shared_from_this, StoppableTask int m_iPollIntSec; int m_iMissedPongs; std::string m_sLastMessage; - boost::asio::io_service *m_Ios; + boost::asio::io_context *m_Ioc; boost::asio::ip::tcp::socket *m_Socket; std::array m_Buffer; }; @@ -243,5 +243,5 @@ class CKodi : public CDomoticzHardwareBase int m_iPingTimeoutms; std::shared_ptr m_thread; std::mutex m_mutex; - boost::asio::io_service m_ios; + boost::asio::io_context m_ioc; }; diff --git hardware/MQTTAutoDiscover.h hardware/MQTTAutoDiscover.h index 0832664..1501d6f 100644 --- hardware/MQTTAutoDiscover.h +++ hardware/MQTTAutoDiscover.h @@ -176,7 +176,7 @@ public: void on_message(const struct mosquitto_message *message) override; void on_connect(int rc) override; void on_disconnect(int rc) override; - void on_going_down(); + void on_going_down() override; private: void InsertUpdateSwitch(_tMQTTASensor* pSensor); diff --git hardware/PanasonicTV.cpp hardware/PanasonicTV.cpp index fc57d34..ce20565 100644 --- hardware/PanasonicTV.cpp +++ hardware/PanasonicTV.cpp @@ -356,18 +356,17 @@ std::string CPanasonicNode::handleWriteAndRead(const std::string& pMessageToSend { _log.Debug(DEBUG_HARDWARE, "Panasonic Plugin: (%s) Handling message: '%s'.", m_Name.c_str(), pMessageToSend.c_str()); - boost::asio::io_service io_service; + boost::asio::io_context io_context; // Get a list of endpoints corresponding to the server name. - boost::asio::ip::tcp::resolver resolver(io_service); - boost::asio::ip::tcp::resolver::query query(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1))); - auto iter = resolver.resolve(query); + boost::asio::ip::tcp::resolver resolver(io_context); + auto endpoints = resolver.resolve(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1))); + auto iter = endpoints.begin(); boost::asio::ip::tcp::endpoint endpoint = *iter; - boost::asio::ip::tcp::resolver::iterator end; // Try each endpoint until we successfully establish a connection. - boost::asio::ip::tcp::socket socket(io_service); + boost::asio::ip::tcp::socket socket(io_context); boost::system::error_code error = boost::asio::error::host_not_found; - while (error && iter != end) + while (error && iter != endpoints.end()) { socket.close(); if (handleConnect(socket, *iter, error)) @@ -1060,7 +1059,7 @@ void CPanasonic::ReloadNodes() { UnloadNodes(); - //m_ios.reset(); // in case this is not the first time in + //m_ioc.reset(); // in case this is not the first time in std::vector > result; result = m_sql.safe_query("SELECT ID,Name,MacAddress,Timeout FROM WOLNodes WHERE (HardwareID==%d)", m_HwdID); @@ -1088,10 +1087,10 @@ void CPanasonic::UnloadNodes() { std::lock_guard l(m_mutex); - m_ios.stop(); // stop the service if it is running + m_ioc.stop(); // stop the service if it is running sleep_milliseconds(100); - while (((!m_pNodes.empty()) || (!m_ios.stopped()))) + while (((!m_pNodes.empty()) || (!m_ioc.stopped()))) { for (auto itt = m_pNodes.begin(); itt != m_pNodes.end(); ++itt) { diff --git hardware/PanasonicTV.h hardware/PanasonicTV.h index b0a94ff..30e1ca1 100644 --- hardware/PanasonicTV.h +++ hardware/PanasonicTV.h @@ -39,7 +39,7 @@ class CPanasonic : public CDomoticzHardwareBase bool m_bTryIfOff; std::shared_ptr m_thread; std::mutex m_mutex; - boost::asio::io_service m_ios; + boost::asio::io_context m_ioc; friend class CPanasonicNode; }; diff --git hardware/Pinger.cpp hardware/Pinger.cpp index a66c7a1..e070b29 100644 --- hardware/Pinger.cpp +++ hardware/Pinger.cpp @@ -21,23 +21,23 @@ #if BOOST_VERSION >= 107000 #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context()) #else -#define GET_IO_SERVICE(s) ((s).get_io_service()) +#define GET_IO_SERVICE(s) ((s).get_io_context()) #endif class pinger : private domoticz::noncopyable { public: - pinger(boost::asio::io_service &io_service, const char *destination, const int iPingTimeoutms) + pinger(boost::asio::io_context &io_context, const char *destination, const int iPingTimeoutms) : num_replies_(0) , m_PingState(false) - , resolver_(io_service) - , socket_(io_service, boost::asio::ip::icmp::v4()) - , timer_(io_service) + , resolver_(io_context) + , socket_(io_context, boost::asio::ip::icmp::v4()) + , timer_(io_context) , sequence_number_(0) { - boost::asio::ip::icmp::resolver::query query(boost::asio::ip::icmp::v4(), destination, ""); - destination_ = *resolver_.resolve(query); + auto endpoints = resolver_.resolve(boost::asio::ip::icmp::v4(), destination, ""); + destination_ = endpoints.begin()->endpoint(); num_tries_ = 1; PingTimeoutms_ = iPingTimeoutms; @@ -332,11 +332,11 @@ void CPinger::ReloadNodes() void CPinger::Do_Ping_Worker(const PingNode &Node) { bool bPingOK = false; - boost::asio::io_service io_service; + boost::asio::io_context io_context; try { - pinger p(io_service, Node.IP.c_str(), m_iPingTimeoutms); - io_service.run(); + pinger p(io_context, Node.IP.c_str(), m_iPingTimeoutms); + io_context.run(); if (p.m_PingState == true) { bPingOK = true; diff --git hardware/RFLinkMQTT.h hardware/RFLinkMQTT.h index e938328..72433b8 100644 --- hardware/RFLinkMQTT.h +++ hardware/RFLinkMQTT.h @@ -46,7 +46,7 @@ protected: boost::signals2::connection m_sDeviceReceivedConnection; boost::signals2::connection m_sSwitchSceneConnection; void selectNextIPAdress( void ); - virtual bool WriteInt(const std::string &sendString); // override; + bool WriteInt(const std::string &sendString) override; void Do_Work(); virtual void SendHeartbeat(); void StopMQTT(); diff --git hardware/TCPProxy/tcpproxy_server.cpp hardware/TCPProxy/tcpproxy_server.cpp index 8aceb0b..d77d4bf 100644 --- hardware/TCPProxy/tcpproxy_server.cpp +++ hardware/TCPProxy/tcpproxy_server.cpp @@ -18,12 +18,12 @@ #if BOOST_VERSION >= 107000 #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context()) #else -#define GET_IO_SERVICE(s) ((s).get_io_service()) +#define GET_IO_SERVICE(s) ((s).get_io_context()) #endif namespace tcp_proxy { - bridge::bridge(boost::asio::io_service& ios) + bridge::bridge(boost::asio::io_context& ios) : downstream_socket_(ios), upstream_socket_(ios) { @@ -44,7 +44,7 @@ namespace tcp_proxy boost::asio::ip::tcp::endpoint end; - boost::asio::io_service &ios= GET_IO_SERVICE(downstream_socket_); + boost::asio::io_context &ios= GET_IO_SERVICE(downstream_socket_); boost::asio::ip::tcp::resolver resolver(ios); boost::asio::ip::tcp::resolver::query query(upstream_host, upstream_port, boost::asio::ip::resolver_query_base::numeric_service); auto i = resolver.resolve(query); @@ -137,10 +137,10 @@ namespace tcp_proxy } //Acceptor Class acceptor::acceptor(const std::string &local_host, unsigned short local_port, const std::string &upstream_host, const std::string &upstream_port) - : io_service_() + : io_context_() , m_bDoStop(false) , localhost_address(boost::asio::ip::address_v4::from_string(local_host)) - , acceptor_(io_service_, boost::asio::ip::tcp::endpoint(localhost_address, local_port)) + , acceptor_(io_context_, boost::asio::ip::tcp::endpoint(localhost_address, local_port)) , upstream_host_(upstream_host) , upstream_port_(upstream_port) { @@ -151,7 +151,7 @@ namespace tcp_proxy { try { - session_ = std::make_shared(io_service_); + session_ = std::make_shared(io_context_); session_->sDownstreamData.connect([this](auto d, auto l) { OnDownstreamData(d, l); }); session_->sUpstreamData.connect([this](auto d, auto l) { OnUpstreamData(d, l); }); @@ -169,11 +169,11 @@ namespace tcp_proxy m_bDoStop=false; accept_connections(); - // 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_context_.run(); return true; } bool acceptor::stop() @@ -181,14 +181,14 @@ namespace tcp_proxy m_bDoStop=true; // Post a call to the stop function so that server::stop() is safe to call // from any thread. - io_service_.post([this] { handle_stop(); }); + io_context_.post([this] { handle_stop(); }); return true; } void acceptor::handle_stop() { // The server is stopped by canceling 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. acceptor_.close(); //connection_manager_.stop_all(); diff --git hardware/TCPProxy/tcpproxy_server.h hardware/TCPProxy/tcpproxy_server.h index 3d1a150..148e65f 100644 --- hardware/TCPProxy/tcpproxy_server.h +++ hardware/TCPProxy/tcpproxy_server.h @@ -10,7 +10,7 @@ namespace tcp_proxy class bridge : public std::enable_shared_from_this { public: - explicit bridge(boost::asio::io_service& ios); + explicit bridge(boost::asio::io_context& ios); boost::asio::ip::tcp::socket& downstream_socket(); boost::asio::ip::tcp::socket& upstream_socket(); @@ -52,8 +52,8 @@ namespace tcp_proxy void OnUpstreamData(const unsigned char *pData, size_t Len); void OnDownstreamData(const unsigned char *pData, size_t Len); - /// 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_context_; bool m_bDoStop; boost::asio::ip::address_v4 localhost_address; boost::asio::ip::tcp::acceptor acceptor_; diff --git hardware/XiaomiDeviceSupport.h hardware/XiaomiDeviceSupport.h index fad7884..4a76d96 100644 --- hardware/XiaomiDeviceSupport.h +++ hardware/XiaomiDeviceSupport.h @@ -15,6 +15,7 @@ class XiaomiDeviceSupport { public: + virtual ~XiaomiDeviceSupport() = default; /** * Method to get 'model' corresponding to the ID of the device in case the Gateway API didn't provide it. * diff --git hardware/XiaomiGateway.cpp hardware/XiaomiGateway.cpp index 66acdc5..fb4387a 100644 --- hardware/XiaomiGateway.cpp +++ hardware/XiaomiGateway.cpp @@ -538,12 +538,12 @@ bool XiaomiGateway::SendMessageToGateway(const std::string &controlmessage) { std::string message = controlmessage; bool result = true; - boost::asio::io_service io_service; - boost::asio::ip::udp::socket socket_(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)); + boost::asio::io_context io_context; + boost::asio::ip::udp::socket socket_(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)); stdreplace(message, "@gatewaykey", GetGatewayKey()); std::shared_ptr message1(new std::string(message)); boost::asio::ip::udp::endpoint remote_endpoint_; - remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(m_GatewayIp), 9898); + remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(m_GatewayIp), 9898); socket_.send_to(boost::asio::buffer(*message1), remote_endpoint_); sleep_milliseconds(150); // TODO: reduce or remove sleep std::array recv_buffer_; @@ -1015,15 +1015,14 @@ bool XiaomiGateway::StopHardware() void XiaomiGateway::Do_Work() { Log(LOG_STATUS, "XiaomiGateway (ID=%d): Worker started...", m_HwdID); - boost::asio::io_service io_service; + boost::asio::io_context io_context; // Find the local ip address that is similar to the xiaomi gateway try { - boost::asio::ip::udp::resolver resolver(io_service); - boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), m_GatewayIp, ""); - auto endpoints = resolver.resolve(query); - boost::asio::ip::udp::endpoint ep = *endpoints; - boost::asio::ip::udp::socket socket(io_service); + boost::asio::ip::udp::resolver resolver(io_context); + auto endpoints = resolver.resolve(boost::asio::ip::udp::v4(), m_GatewayIp, ""); + boost::asio::ip::udp::endpoint ep = *endpoints.begin(); + boost::asio::ip::udp::socket socket(io_context); socket.connect(ep); boost::asio::ip::address addr = socket.local_endpoint().address(); std::string compareIp = m_GatewayIp.substr(0, (m_GatewayIp.length() - 3)); @@ -1073,11 +1072,11 @@ void XiaomiGateway::Do_Work() } } - XiaomiGateway::xiaomi_udp_server udp_server(io_service, m_HwdID, m_GatewayIp, m_LocalIp, m_ListenPort9898, m_OutputMessage, m_IncludeVoltage, this); + XiaomiGateway::xiaomi_udp_server udp_server(io_context, m_HwdID, m_GatewayIp, m_LocalIp, m_ListenPort9898, m_OutputMessage, m_IncludeVoltage, this); boost::thread bt; if (m_ListenPort9898) { - bt = boost::thread([p = &io_service] { p->run(); }); + bt = boost::thread([p = &io_context] { p->run(); }); SetThreadName(bt.native_handle(), "XiaomiGatewayIO"); } @@ -1094,7 +1093,7 @@ void XiaomiGateway::Do_Work() // Log(LOG_STATUS, "sec_counter %d", sec_counter); } } - io_service.stop(); + io_context.stop(); if (bt.joinable()) { bt.join(); @@ -1178,9 +1177,9 @@ unsigned int XiaomiGateway::GetShortID(const std::string &nodeid) return sID; } -XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_service, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, const bool listenPort9898, +XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_context &io_context, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, const bool listenPort9898, const bool outputMessage, const bool includeVoltage, XiaomiGateway *parent) - : socket_(io_service, boost::asio::ip::udp::v4()) + : socket_(io_context, boost::asio::ip::udp::v4()) { m_HardwareID = m_HwdID; m_XiaomiGateway = parent; @@ -1196,8 +1195,8 @@ XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_ if (!m_localip.empty()) { boost::system::error_code ec; - boost::asio::ip::address listen_addr = boost::asio::ip::address::from_string(m_localip, ec); - boost::asio::ip::address mcast_addr = boost::asio::ip::address::from_string("224.0.0.50", ec); + boost::asio::ip::address listen_addr = boost::asio::ip::make_address_v4(m_localip, ec); + boost::asio::ip::address mcast_addr = boost::asio::ip::make_address_v4("224.0.0.50", ec); boost::asio::ip::udp::endpoint listen_endpoint(mcast_addr, 9898); socket_.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 9898)); @@ -1213,9 +1212,9 @@ XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_ socket_.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 9898)); std::shared_ptr message(new std::string(R"({"cmd":"whois"})")); boost::asio::ip::udp::endpoint remote_endpoint; - remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("224.0.0.50"), 4321); + remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4("224.0.0.50"), 4321); socket_.send_to(boost::asio::buffer(*message), remote_endpoint); - socket_.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string("224.0.0.50"))); + socket_.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::make_address_v4("224.0.0.50"))); } } catch (const boost::system::system_error &ex) @@ -1720,7 +1719,7 @@ void XiaomiGateway::xiaomi_udp_server::handle_receive(const boost::system::error message.append("\"}"); std::shared_ptr message1(new std::string(message)); boost::asio::ip::udp::endpoint remote_endpoint; - remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(TrueGateway->GetGatewayIp().c_str()), 9898); + remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(TrueGateway->GetGatewayIp().c_str()), 9898); socket_.send_to(boost::asio::buffer(*message1), remote_endpoint); } } @@ -1746,7 +1745,7 @@ void XiaomiGateway::xiaomi_udp_server::handle_receive(const boost::system::error std::string message = R"({"cmd" : "get_id_list"})"; std::shared_ptr message2(new std::string(message)); boost::asio::ip::udp::endpoint remote_endpoint; - remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(TrueGateway->GetGatewayIp().c_str()), 9898); + remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(TrueGateway->GetGatewayIp().c_str()), 9898); socket_.send_to(boost::asio::buffer(*message2), remote_endpoint); } } diff --git hardware/XiaomiGateway.h hardware/XiaomiGateway.h index dce4b34..1f552f3 100644 --- hardware/XiaomiGateway.h +++ hardware/XiaomiGateway.h @@ -100,7 +100,7 @@ class XiaomiGateway : public CDomoticzHardwareBase class xiaomi_udp_server { public: - xiaomi_udp_server(boost::asio::io_service &io_service, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, bool listenPort9898, bool outputMessage, + xiaomi_udp_server(boost::asio::io_context &io_context, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, bool listenPort9898, bool outputMessage, bool includeVolage, XiaomiGateway *parent); ~xiaomi_udp_server() = default; diff --git hardware/Yeelight.cpp hardware/Yeelight.cpp index cdb7889..e5fe8fc 100644 --- hardware/Yeelight.cpp +++ hardware/Yeelight.cpp @@ -93,8 +93,8 @@ void Yeelight::Do_Work() try { - boost::asio::io_service io_service; - udp_server server(io_service, m_HwdID); + boost::asio::io_context io_context; + udp_server server(io_context, m_HwdID); int sec_counter = YEELIGHT_POLL_INTERVAL - 5; while (!IsStopRequested(1000)) { @@ -105,7 +105,7 @@ void Yeelight::Do_Work() if (sec_counter % 60 == 0) //poll YeeLights every minute { server.start_send(); - io_service.run(); + io_context.run(); } } } @@ -227,12 +227,11 @@ bool Yeelight::WriteToHardware(const char *pdata, const unsigned char length) try { - boost::asio::io_service io_service; - boost::asio::ip::tcp::socket sendSocket(io_service); - boost::asio::ip::tcp::resolver resolver(io_service); - boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), szTmp, "55443"); - auto iterator = resolver.resolve(query); - boost::asio::connect(sendSocket, iterator); + boost::asio::io_context io_context; + boost::asio::ip::tcp::socket sendSocket(io_context); + boost::asio::ip::tcp::resolver resolver(io_context); + auto endpoints = resolver.resolve(boost::asio::ip::tcp::v4(), szTmp, "55443"); + boost::asio::connect(sendSocket, endpoints); std::string message; std::string message2; @@ -404,8 +403,8 @@ bool Yeelight::WriteToHardware(const char *pdata, const unsigned char length) std::array recv_buffer_; int hardwareId; -Yeelight::udp_server::udp_server(boost::asio::io_service& io_service, int m_HwdID) - : socket_(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) +Yeelight::udp_server::udp_server(boost::asio::io_context& io_context, int m_HwdID) + : socket_(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) { socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true)); socket_.set_option(boost::asio::socket_base::broadcast(true)); @@ -421,7 +420,7 @@ void Yeelight::udp_server::start_send() //Log(LOG_STATUS, "start_send.................."); std::shared_ptr message( new std::string(testMessage)); - remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("239.255.255.250"), 1982); + remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4("239.255.255.250"), 1982); socket_.send_to(boost::asio::buffer(*message), remote_endpoint_); sleep_milliseconds(150); start_receive(); diff --git hardware/Yeelight.h hardware/Yeelight.h index fb03c28..3b7b4c3 100644 --- hardware/Yeelight.h +++ hardware/Yeelight.h @@ -25,7 +25,7 @@ class Yeelight : public CDomoticzHardwareBase class udp_server { public: - udp_server(boost::asio::io_service &io_service, int m_HwdID); + udp_server(boost::asio::io_context &io_context, int m_HwdID); boost::asio::ip::udp::socket socket_; boost::asio::ip::udp::endpoint remote_endpoint_; void start_send(); diff --git hardware/plugins/PluginManager.cpp hardware/plugins/PluginManager.cpp index 2813112..423edbb 100644 --- hardware/plugins/PluginManager.cpp +++ hardware/plugins/PluginManager.cpp @@ -64,7 +64,7 @@ namespace Plugins { // PyMODINIT_FUNC PyInit_DomoticzEvents(void); std::mutex PluginMutex; // controls accessto the message queue and m_pPlugins map - boost::asio::io_service ios; + boost::asio::io_context ios; std::map CPluginSystem::m_pPlugins; std::map CPluginSystem::m_PluginXml; @@ -315,7 +315,7 @@ namespace Plugins { // Create initial IO Service thread ios.restart(); // Create some work to keep IO Service alive - auto work = boost::asio::io_service::work(ios); + auto work = boost::asio::make_work_guard(ios); boost::thread_group BoostThreads; for (int i = 0; i < 1; i++) { diff --git hardware/plugins/PluginTransports.cpp hardware/plugins/PluginTransports.cpp index 52d14e7..f7ace0f 100644 --- hardware/plugins/PluginTransports.cpp +++ hardware/plugins/PluginTransports.cpp @@ -116,15 +116,14 @@ namespace Plugins { m_bConnected = false; m_Socket = new boost::asio::ip::tcp::socket(ios); - boost::system::error_code ec; - boost::asio::ip::tcp::resolver::query query(m_IP, m_Port); - auto iter = m_Resolver.resolve(query); - boost::asio::ip::tcp::endpoint endpoint = *iter; - // // Async resolve/connect based on http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/http/client/async_client.cpp // - m_Resolver.async_resolve(query, [this](auto &&err, auto end) { handleAsyncResolve(err, end); }); + m_Resolver.async_resolve(m_IP, m_Port, + [this](auto &&err, auto endpoints) { + handleAsyncResolve(err, endpoints); + } + ); } } catch (std::exception& e) @@ -139,15 +138,14 @@ namespace Plugins { return true; } - void CPluginTransportTCP::handleAsyncResolve(const boost::system::error_code & err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) + void CPluginTransportTCP::handleAsyncResolve(const boost::system::error_code & err, boost::asio::ip::tcp::resolver::results_type endpoints) { CPlugin* pPlugin = ((CConnection*)m_pConnection)->pPlugin; AccessPython Guard(pPlugin, "CPluginTransportTCP::handleAsyncResolve"); if (!err) { - boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator; - m_Socket->async_connect(endpoint, [this, endpoint_iterator](auto &&err) mutable { handleAsyncConnect(err, ++endpoint_iterator); }); + boost::asio::async_connect(*m_Socket, endpoints, [this](auto &&err, const boost::asio::ip::tcp::endpoint &endpoint) mutable { handleAsyncConnect(err, endpoint); }); } else { @@ -169,7 +167,7 @@ namespace Plugins { } } - void CPluginTransportTCP::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) + void CPluginTransportTCP::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint) { CPlugin* pPlugin = ((CConnection*)m_pConnection)->pPlugin; AccessPython Guard(pPlugin, "CPluginTransportTCP::handleAsyncResolve"); @@ -481,7 +479,7 @@ namespace Plugins { } }; - void CPluginTransportTCPSecure::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) + void CPluginTransportTCPSecure::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint) { CPlugin* pPlugin = ((CConnection*)m_pConnection)->pPlugin; if (!pPlugin) return; @@ -498,7 +496,7 @@ namespace Plugins { SSL_set_tlsext_host_name(m_TLSSock->native_handle(), m_IP.c_str()); // Enable SNI m_TLSSock->set_verify_mode(boost::asio::ssl::verify_none); - m_TLSSock->set_verify_callback(boost::asio::ssl::rfc2818_verification(m_IP)); + m_TLSSock->set_verify_callback(boost::asio::ssl::host_name_verification(m_IP)); // m_TLSSock->set_verify_callback([this](auto v, auto &c){ VerifyCertificate(v, c);}); try { @@ -648,7 +646,7 @@ namespace Plugins { // Hanlde multicast if (((m_IP.substr(0, 4) >= "224.") && (m_IP.substr(0, 4) <= "239.")) || (m_IP.substr(0, 4) == "255.")) { - m_Socket->set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string(m_IP.c_str())), ec); + m_Socket->set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::make_address_v4(m_IP.c_str())), ec); m_Socket->set_option(boost::asio::ip::multicast::hops(2), ec); } } @@ -764,7 +762,7 @@ namespace Plugins { } else { - boost::asio::ip::udp::endpoint destination(boost::asio::ip::address::from_string(m_IP.c_str()), atoi(m_Port.c_str())); + boost::asio::ip::udp::endpoint destination(boost::asio::ip::make_address_v4(m_IP.c_str()), atoi(m_Port.c_str())); size_t bytes_transferred = m_Socket->send_to(boost::asio::buffer(pMessage, pMessage.size()), destination); } } @@ -825,12 +823,14 @@ namespace Plugins { } }; - void CPluginTransportICMP::handleAsyncResolve(const boost::system::error_code &ec, const boost::asio::ip::icmp::resolver::iterator &endpoint_iterator) + void CPluginTransportICMP::handleAsyncResolve(const boost::system::error_code &ec, boost::asio::ip::icmp::resolver::results_type endpoints) { if (!ec) { + m_Endpoint = endpoints.begin()->endpoint(); + m_IP = m_Endpoint.address().to_string(); + m_bConnected = true; - m_IP = endpoint_iterator->endpoint().address().to_string(); // Listen will fail (10022 - bad parameter) unless something has been sent(?) std::string body("ping"); @@ -857,15 +857,11 @@ namespace Plugins { m_bConnecting = true; m_Socket = new boost::asio::ip::icmp::socket(ios, boost::asio::ip::icmp::v4()); - boost::system::error_code ec; - boost::asio::ip::icmp::resolver::query query(boost::asio::ip::icmp::v4(), m_IP, ""); - auto iter = m_Resolver.resolve(query); - m_Endpoint = *iter; - - // - // Async resolve/connect based on http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/example/icmp/ping.cpp - // - m_Resolver.async_resolve(query, [this](auto &&err, auto i) { handleAsyncResolve(err, i); }); + m_Resolver.async_resolve(boost::asio::ip::icmp::v4(), m_IP, "", + [this](auto &&err, auto endpoints) { + handleAsyncResolve(err, endpoints); + } + ); } else { diff --git hardware/plugins/PluginTransports.h hardware/plugins/PluginTransports.h index c1cc1e3..79d5725 100644 --- hardware/plugins/PluginTransports.h +++ hardware/plugins/PluginTransports.h @@ -6,7 +6,7 @@ namespace Plugins { - extern boost::asio::io_service ios; + extern boost::asio::io_context ios; class CPluginTransport { @@ -85,8 +85,8 @@ namespace Plugins { , m_Socket(nullptr){}; bool handleConnect() override; bool handleListen() override; - virtual void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator); - virtual void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator); + virtual void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::results_type endpoints); + virtual void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint); virtual void handleAsyncAccept(boost::asio::ip::tcp::socket *pSocket, const boost::system::error_code &error); void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override; void handleWrite(const std::vector &pMessage) override; @@ -111,7 +111,7 @@ namespace Plugins { : CPluginTransportTCP(HwdID, pConnection, Address, Port) , m_Context(nullptr) , m_TLSSock(nullptr){}; - void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) override; + void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint) override; void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override; void handleWrite(const std::vector &pMessage) override; ~CPluginTransportTCPSecure() override; @@ -151,7 +151,7 @@ namespace Plugins { , m_Socket(nullptr) , m_Timer(nullptr) , m_SequenceNo(-1){}; - void handleAsyncResolve(const boost::system::error_code &err, const boost::asio::ip::icmp::resolver::iterator &endpoint_iterator); + void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::icmp::resolver::results_type endpoints); bool handleListen() override; void handleTimeout(const boost::system::error_code &) override; void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override; diff --git main/WebServerCmds.cpp main/WebServerCmds.cpp index 7d4a9f2..3586373 100644 --- main/WebServerCmds.cpp +++ main/WebServerCmds.cpp @@ -1632,7 +1632,7 @@ namespace http ExtraHeaders.push_back("App_Revision: " + std::to_string(iAppRevision)); ExtraHeaders.push_back("System_Name: " + systemname); ExtraHeaders.push_back("Machine: " + machine); - ExtraHeaders.push_back("Type: " + (!bIsBetaChannel) ? "Stable" : "Beta"); + ExtraHeaders.push_back("Type: " + std::string(!bIsBetaChannel ? "Stable" : "Beta")); if (!HTTPClient::GET(szHistoryURL, ExtraHeaders, historyfile)) { diff --git main/mainworker.cpp main/mainworker.cpp index b5027eb..b8f8dc7 100644 --- main/mainworker.cpp +++ main/mainworker.cpp @@ -1318,7 +1318,7 @@ bool MainWorker::IsUpdateAvailable(const bool bIsForced) ExtraHeaders.push_back("App_Revision: " + std::to_string(iAppRevision)); ExtraHeaders.push_back("System_Name: " + m_szSystemName); ExtraHeaders.push_back("Machine: " + machine); - ExtraHeaders.push_back("Type: " + (!bIsBetaChannel) ? "Stable" : "Beta"); + ExtraHeaders.push_back("Type: " + std::string(!bIsBetaChannel ? "Stable" : "Beta")); if (!HTTPClient::GET(szURL, ExtraHeaders, revfile)) return false; diff --git plugins/examples/Pinger.py plugins/examples/Pinger.py index 6b54559..c7a776d 100644 --- plugins/examples/Pinger.py +++ plugins/examples/Pinger.py @@ -3,7 +3,7 @@ # Author: Dnpwwo, 2017 - 2018 # """ - + ICMP Pinger Plugin.

Specify comma delimted addresses (IP or DNS names) of devices that are to be pinged.
@@ -144,8 +144,9 @@ class BasePlugin: for Device in Devices: if (("Name" in Devices[Device].Options) and (Devices[Device].Options["Name"] == Connection.Name)): UpdateDevice(Device, 0, "Off", TimedOut) - self.icmpConn.Close() - self.icmpConn = None + if (self.icmpConn != None): + self.icmpConn.Close() + self.icmpConn = None def onHeartbeat(self): Domoticz.Debug("Heartbeating...") diff --git push/MQTTPush.h push/MQTTPush.h index 0773b43..d9f9332 100644 --- push/MQTTPush.h +++ push/MQTTPush.h @@ -14,7 +14,7 @@ public: void on_message(const struct mosquitto_message* message) override; void on_connect(int rc) override; void on_disconnect(int rc) override; - void on_going_down(); + void on_going_down() override; private: struct _tPushItem { diff --git tcpserver/TCPClient.cpp tcpserver/TCPClient.cpp index d55da10..3eee093 100644 --- tcpserver/TCPClient.cpp +++ tcpserver/TCPClient.cpp @@ -19,7 +19,7 @@ namespace tcp { delete socket_; } - CTCPClient::CTCPClient(boost::asio::io_service& ios, CTCPServerIntBase* pManager) + CTCPClient::CTCPClient(boost::asio::io_context& ios, CTCPServerIntBase* pManager) : CTCPClientBase(pManager) { socket_ = new boost::asio::ip::tcp::socket(ios); diff --git tcpserver/TCPClient.h tcpserver/TCPClient.h index df4350d..e7a882b 100644 --- tcpserver/TCPClient.h +++ tcpserver/TCPClient.h @@ -38,7 +38,7 @@ class CTCPClient : public CTCPClientBase, public std::enable_shared_from_this { public: - CTCPClient(boost::asio::io_service& ios, CTCPServerIntBase *pManager); + CTCPClient(boost::asio::io_context& ios, CTCPServerIntBase *pManager); ~CTCPClient() = default; void start() override; void stop() override; diff --git tcpserver/TCPServer.cpp tcpserver/TCPServer.cpp index 91fdc7e..57f8709 100644 --- tcpserver/TCPServer.cpp +++ tcpserver/TCPServer.cpp @@ -18,14 +18,14 @@ namespace tcp { CTCPServerInt::CTCPServerInt(const std::string& address, const std::string& port, CTCPServer* pRoot) : CTCPServerIntBase(pRoot), - io_service_(), - acceptor_(io_service_) + io_context_(), + acceptor_(io_context_) { // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). - boost::asio::ip::tcp::resolver resolver(io_service_); - boost::asio::ip::tcp::resolver::query query(address, port); - boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); - acceptor_.open(endpoint.protocol()); + boost::asio::ip::tcp::resolver resolver(io_context_); + boost::asio::ip::basic_resolver::results_type endpoints = resolver.resolve(address, port); + auto endpoint = *endpoints.begin(); + acceptor_.open(endpoint.endpoint().protocol()); acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); // bind to both ipv6 and ipv4 sockets for the "::" address only if (address == "::") @@ -35,7 +35,7 @@ namespace tcp { acceptor_.bind(endpoint); acceptor_.listen(); - new_connection_ = std::make_shared(io_service_, this); + new_connection_ = std::make_shared(io_context_, this); if (new_connection_ == nullptr) { _log.Log(LOG_ERROR, "Error creating new client!"); @@ -47,24 +47,24 @@ namespace tcp { void CTCPServerInt::start() { - // 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_context_.run(); } void CTCPServerInt::stop() { // Post a call to the stop function so that server::stop() is safe to call // from any thread. - io_service_.post([this] { handle_stop(); }); + boost::asio::post([this] { handle_stop(); }); } void CTCPServerInt::handle_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. acceptor_.close(); stopAllClients(); @@ -88,7 +88,7 @@ namespace tcp { connections_.insert(new_connection_); new_connection_->start(); - new_connection_.reset(new CTCPClient(io_service_, this)); + new_connection_.reset(new CTCPClient(io_context_, this)); acceptor_.async_accept(*(new_connection_->socket()), [this](auto&& err) { handleAccept(err); }); } diff --git tcpserver/TCPServer.h tcpserver/TCPServer.h index ca611b1..17284ca 100644 --- tcpserver/TCPServer.h +++ tcpserver/TCPServer.h @@ -70,8 +70,8 @@ private: /// Handle a request to stop the server. void handle_stop(); - /// 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_context_; boost::asio::ip::tcp::acceptor acceptor_; diff --git webserver/cWebem.cpp webserver/cWebem.cpp index 57d9683..c0d292d 100644 --- webserver/cWebem.cpp +++ webserver/cWebem.cpp @@ -47,13 +47,13 @@ namespace http { , myRequestHandler(doc_root, this) // Rene, make sure we initialize m_sessions first, before starting a server , myServer(server_factory::create(settings, myRequestHandler)) - , m_io_service() - , m_session_clean_timer(m_io_service, boost::posix_time::minutes(1)) + , m_io_context() + , m_session_clean_timer(m_io_context, boost::posix_time::minutes(1)) { // associate handler to timer and schedule the first iteration m_session_clean_timer.async_wait([this](auto &&) { CleanSessions(); }); - m_io_service_thread = std::make_shared([p = &m_io_service] { p->run(); }); - SetThreadName(m_io_service_thread->native_handle(), "Webem_ssncleaner"); + m_io_context_thread = std::make_shared([p = &m_io_context] { p->run(); }); + SetThreadName(m_io_context_thread->native_handle(), "Webem_ssncleaner"); } cWebem::~cWebem() @@ -93,14 +93,14 @@ namespace http { // Stop session cleaner try { - if (!m_io_service.stopped()) + if (!m_io_context.stopped()) { - m_io_service.stop(); + m_io_context.stop(); } - if (m_io_service_thread) + if (m_io_context_thread) { - m_io_service_thread->join(); - m_io_service_thread.reset(); + m_io_context_thread->join(); + m_io_context_thread.reset(); } } catch (...) diff --git webserver/cWebem.h webserver/cWebem.h index 6e3b899..7905c45 100644 --- webserver/cWebem.h +++ webserver/cWebem.h @@ -259,9 +259,9 @@ namespace http std::string m_webRoot; /// sessions management std::mutex m_sessionsMutex; - boost::asio::io_service m_io_service; + boost::asio::io_context m_io_context; boost::asio::deadline_timer m_session_clean_timer; - std::shared_ptr m_io_service_thread; + std::shared_ptr m_io_context_thread; }; } // namespace server diff --git webserver/connection.cpp webserver/connection.cpp index 40f9788..3a70924 100644 --- webserver/connection.cpp +++ webserver/connection.cpp @@ -22,13 +22,13 @@ namespace http { extern time_t last_write_time(const std::string& path); // this is the constructor for plain connections - connection::connection(boost::asio::io_service &io_service, connection_manager &manager, request_handler &handler, int read_timeout) + connection::connection(boost::asio::io_context &io_context, connection_manager &manager, request_handler &handler, int read_timeout) : send_buffer_(nullptr) , read_timeout_(read_timeout) - , read_timer_(io_service, boost::posix_time::seconds(read_timeout)) + , read_timer_(io_context, boost::posix_time::seconds(read_timeout)) , default_abandoned_timeout_(20 * 60) // 20mn before stopping abandoned connection - , abandoned_timer_(io_service, boost::posix_time::seconds(default_abandoned_timeout_)) + , abandoned_timer_(io_context, boost::posix_time::seconds(default_abandoned_timeout_)) , connection_manager_(manager) , request_handler_(handler) , status_(INITIALIZING) @@ -39,18 +39,18 @@ namespace http { keepalive_ = false; write_in_progress = false; connection_type = ConnectionType::connection_http; - socket_ = std::make_unique(io_service); + socket_ = std::make_unique(io_context); } #ifdef WWW_ENABLE_SSL // this is the constructor for secure connections - connection::connection(boost::asio::io_service &io_service, connection_manager &manager, request_handler &handler, int read_timeout, boost::asio::ssl::context &context) + connection::connection(boost::asio::io_context &io_context, connection_manager &manager, request_handler &handler, int read_timeout, boost::asio::ssl::context &context) : send_buffer_(nullptr) , read_timeout_(read_timeout) - , read_timer_(io_service, boost::posix_time::seconds(read_timeout)) + , read_timer_(io_context, boost::posix_time::seconds(read_timeout)) , default_abandoned_timeout_(20 * 60) // 20mn before stopping abandoned connection - , abandoned_timer_(io_service, boost::posix_time::seconds(default_abandoned_timeout_)) + , abandoned_timer_(io_context, boost::posix_time::seconds(default_abandoned_timeout_)) , connection_manager_(manager) , request_handler_(handler) , status_(INITIALIZING) @@ -62,7 +62,7 @@ namespace http { write_in_progress = false; connection_type = ConnectionType::connection_http; socket_ = nullptr; - sslsocket_ = std::make_unique(io_service, context); + sslsocket_ = std::make_unique(io_context, context); } #endif @@ -152,9 +152,9 @@ namespace http { if (error != boost::asio::error::operation_aborted) { switch (connection_type) { case ConnectionType::connection_http: - // Timers should be cancelled before stopping to remove tasks from the io_service. - // The io_service will stop naturally when every tasks are removed. - // If timers are not cancelled, the exception ERROR_ABANDONED_WAIT_0 is thrown up to the io_service::run() caller. + // Timers should be cancelled before stopping to remove tasks from the io_context. + // The io_context will stop naturally when every tasks are removed. + // If timers are not cancelled, the exception ERROR_ABANDONED_WAIT_0 is thrown up to the io_context::run() caller. cancel_abandoned_timeout(); cancel_read_timeout(); @@ -372,7 +372,7 @@ namespace http { switch (connection_type) { case ConnectionType::connection_http: - begin = boost::asio::buffer_cast(_buf.data()); + begin = static_cast(_buf.data().data()); try { request_parser_.reset(); @@ -404,7 +404,7 @@ namespace http { newt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); } - size_t sizeread = begin - boost::asio::buffer_cast(_buf.data()); + size_t sizeread = begin - static_cast(_buf.data().data()); _buf.consume(sizeread); reply_.reset(); const char* pConnection = request_.get_req_header(&request_, "Connection"); @@ -520,7 +520,7 @@ namespace http { break; case ConnectionType::connection_websocket: case ConnectionType::connection_websocket_closing: - begin = boost::asio::buffer_cast(_buf.data()); + begin = static_cast(_buf.data().data()); result = websocket_parser.parse((const unsigned char*)begin, _buf.size(), bytes_consumed, keepalive_); _buf.consume(bytes_consumed); if (result) { diff --git webserver/connection.hpp webserver/connection.hpp index ce452b5..c1a82c5 100644 --- webserver/connection.hpp +++ webserver/connection.hpp @@ -43,11 +43,11 @@ namespace http { std::string host_local_endpoint_port_; std::string host_last_request_uri_; }; - /// Construct a connection with the given io_service. - explicit connection(boost::asio::io_service& io_service, + /// Construct a connection with the given io_context. + explicit connection(boost::asio::io_context& io_context, connection_manager& manager, request_handler& handler, int timeout); #ifdef WWW_ENABLE_SSL - explicit connection(boost::asio::io_service& io_service, + explicit connection(boost::asio::io_context& io_context, connection_manager& manager, request_handler& handler, int timeout, boost::asio::ssl::context& context); #endif ~connection() = default; diff --git webserver/server.cpp webserver/server.cpp index da15887..8bdfc13 100644 --- webserver/server.cpp +++ webserver/server.cpp @@ -13,15 +13,15 @@ namespace http { namespace server { server_base::server_base(const server_settings &settings, request_handler &user_request_handler) - : io_service_() - , acceptor_(io_service_) + : io_context_() + , acceptor_(io_context_) , request_handler_(user_request_handler) , settings_(settings) , timeout_(20) , // default read timeout in seconds is_running(false) , is_stop_complete(false) - , m_heartbeat_timer(io_service_) + , m_heartbeat_timer(io_context_) { if (!settings.is_enabled()) { @@ -39,10 +39,10 @@ namespace server { } // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). - boost::asio::ip::tcp::resolver resolver(io_service_); - boost::asio::ip::tcp::resolver::query query(settings_.listening_address, settings_.listening_port); - boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); - acceptor_.open(endpoint.protocol()); + boost::asio::ip::tcp::resolver resolver(io_context_); + boost::asio::ip::basic_resolver::results_type endpoints = resolver.resolve(settings_.listening_address, settings_.listening_port); + auto endpoint = *endpoints.begin(); + acceptor_.open(endpoint.endpoint().protocol()); acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); // bind to both ipv6 and ipv4 sockets for the "::" address only if (settings_.listening_address == "::") @@ -59,28 +59,28 @@ namespace server { } void server_base::run() { - // 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. try { is_running = true; heart_beat(boost::system::error_code()); - io_service_.run(); + io_context_.run(); is_running = false; } catch (std::exception& e) { _log.Log(LOG_ERROR, "[web:%s] exception occurred : '%s' (need to run again)", settings_.listening_port.c_str(), e.what()); is_running = false; // Note: if acceptor is up everything is OK, we can call run() again // but if the exception has broken the acceptor we cannot stop/start it and the next run() will exit immediatly. - io_service_.reset(); // this call is needed before calling run() again + io_context_.restart(); // this call is needed before calling run() again throw; } catch (...) { _log.Log(LOG_ERROR, "[web:%s] unknown exception occurred (need to run again)", settings_.listening_port.c_str()); is_running = false; // Note: if acceptor is up everything is OK, we can call run() again // but if the exception has broken the acceptor we cannot stop/start it and the next run() will exit immediatly. - io_service_.reset(); // this call is needed before calling run() again + io_context_.restart(); // this call is needed before calling run() again throw; } } @@ -89,12 +89,12 @@ void server_base::run() { void server_base::stop() { if (is_running) { // Post a call to the stop function so that server_base::stop() is safe to call from any thread. - // Rene, set is_running to false, because the following is an io_service call, which makes is_running + // Rene, set is_running to false, because the following is an io_context call, which makes is_running // never set to false whilst in the call itself is_running = false; - io_service_.post([this] { handle_stop(); }); + boost::asio::post(io_context_, [this] { handle_stop(); }); } else { - // if io_service is not running then the post call will not be performed + // if io_context is not running then the post call will not be performed handle_stop(); } @@ -112,7 +112,7 @@ void server_base::stop() { } sleep_milliseconds(500); } - io_service_.stop(); + io_context_.stop(); // Deregister heartbeat m_mainworker.HeartbeatRemove(std::string("WebServer:") + settings_.listening_port); @@ -136,7 +136,7 @@ void server_base::heart_beat(const boost::system::error_code& error) m_mainworker.HeartbeatUpdate(std::string("WebServer:") + settings_.listening_port); // Schedule next heartbeat - m_heartbeat_timer.expires_from_now(std::chrono::seconds(4)); + m_heartbeat_timer.expires_after(std::chrono::seconds(4)); m_heartbeat_timer.async_wait([this](auto &&err) { heart_beat(err); }); } } @@ -148,7 +148,7 @@ server::server(const server_settings &settings, request_handler &user_request_ha } void server::init_connection() { - new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_)); + new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_)); } /** @@ -157,7 +157,7 @@ void server::init_connection() { void server::handle_accept(const boost::system::error_code& e) { if (!e) { connection_manager_.start(new_connection_); - new_connection_.reset(new connection(io_service_, + new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_)); // listen for a subsequent request acceptor_.async_accept(new_connection_->socket(), [this](auto &&err) { handle_accept(err); }); @@ -267,7 +267,7 @@ void ssl_server::init_connection() { } else { _log.Log(LOG_ERROR, "[web:%s] missing SSL DH parameters file %s!", settings_.listening_port.c_str(), settings_.tmp_dh_file_path.c_str()); } - new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_, context_)); + new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_, context_)); } void ssl_server::reinit_connection() @@ -305,7 +305,7 @@ void ssl_server::reinit_connection() _log.Log(LOG_ERROR, "[web:%s] missing SSL DH parameters from file %s", settings_.listening_port.c_str(), settings_.tmp_dh_file_path.c_str()); } } - new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_, context_)); + new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_, context_)); } /** diff --git webserver/server.hpp webserver/server.hpp index f9e71c5..bd7132a 100644 --- webserver/server.hpp +++ webserver/server.hpp @@ -31,7 +31,7 @@ namespace http explicit server_base(const server_settings &settings, request_handler &user_request_handler); virtual ~server_base() = default; - /// Run the server's io_service loop. + /// Run the server's io_context loop. void run(); /// Stop the server. @@ -46,8 +46,8 @@ namespace http protected: void init(const init_connectionhandler_func &init_connection_handler, accept_handler_func accept_handler); - /// 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_context_; /// Acceptor used to listen for incoming connections. boost::asio::ip::tcp::acceptor acceptor_;