diff options
| author | Stefan Boberg <[email protected]> | 2026-03-12 15:05:04 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-03-12 15:05:04 +0100 |
| commit | 81c87586690ef596561e257e1ddde274848199fd (patch) | |
| tree | 07a2edf8b0e2033603bd805f7d9ac192502e27f7 /src | |
| parent | Transparent proxy mode (#823) (diff) | |
| download | zen-81c87586690ef596561e257e1ddde274848199fd.tar.xz zen-81c87586690ef596561e257e1ddde274848199fd.zip | |
upgrade asio from 1.29.0 to 1.38.0 (#827)
Migrate removed deprecated APIs:
- io_service -> io_context
- io_service::work -> executor_work_guard
- resolver::query/iterator -> resolver::resolve() with results_type
- address::from_string() -> make_address()
---
Breaking Changes (1.33.0)
- deferred as default completion token — can omit token in coroutines: co_await socket.async_read_some(buf)
- cancel_after / cancel_at — timeout any async operation: co_await sock.async_read_some(buf, cancel_after(5s))
- Partial completion token adapters — as_tuple, redirect_error, bind_executor etc. composable via pipe: co_await (async_write(sock, buf) | as_tuple | cancel_after(10s))
- composed — simpler alternative to async_compose for stateful operation implementations
- co_composed moved out of experimental
1.35.0 — Allocator & Resolver
- Allocator constructors for io_context and thread_pool — control memory allocation for services, I/O objects, strands
- Configurable resolver thread pool ("resolver"/"threads")
- Timer heap pre-allocation ("timer"/"heap_reserve")
1.37.0 — Inline Executors & Reactor Tuning
- inline_executor — always executes inline (useful as completion executor)
- inline_or_executor<> — tries inline first, falls back to wrapped executor
- New dispatch/post/defer overloads that run a function on one executor and deliver result to a handler on another
- redirect_disposition — captures disposition into a variable (like redirect_error but generic)
- Reactor config: reset_edge_on_partial_read, use_eventfd, use_timerfd
Notable Fixes
- Resource leak in awaitable move assignment (1.37.0)
- Memory leak in SSL stream move assignment (1.37.0)
- Thread sanitizer issue in kqueue reactor (1.37.0)
- co_spawn non-reentrant completion handler fix (1.36.0)
- Windows file append mode fix (1.32.0)
- SSL engine move assignment leak (1.33.0)
Diffstat (limited to 'src')
| -rw-r--r-- | src/zenhttp/clients/httpwsclient.cpp | 12 | ||||
| -rw-r--r-- | src/zenhttp/servers/httpasio.cpp | 24 | ||||
| -rw-r--r-- | src/zenhttp/servers/httpsys.cpp | 4 | ||||
| -rw-r--r-- | src/zenhttp/servers/wstest.cpp | 18 | ||||
| -rw-r--r-- | src/zenhttp/transports/asiotransport.cpp | 14 | ||||
| -rw-r--r-- | src/zennet/statsdclient.cpp | 9 |
6 files changed, 40 insertions, 41 deletions
diff --git a/src/zenhttp/clients/httpwsclient.cpp b/src/zenhttp/clients/httpwsclient.cpp index 792848a6b..2d566ae86 100644 --- a/src/zenhttp/clients/httpwsclient.cpp +++ b/src/zenhttp/clients/httpwsclient.cpp @@ -125,8 +125,8 @@ struct HttpWsClient::Impl { if (m_OwnedIoContext) { - m_WorkGuard = std::make_unique<asio::io_context::work>(m_IoContext); - m_IoThread = std::thread([this] { m_IoContext.run(); }); + m_WorkGuard.emplace(m_IoContext.get_executor()); + m_IoThread = std::thread([this] { m_IoContext.run(); }); } #if defined(ASIO_HAS_LOCAL_SOCKETS) @@ -564,10 +564,10 @@ struct HttpWsClient::Impl std::string m_Path; // io_context: owned (standalone) or external (shared) - std::unique_ptr<asio::io_context> m_OwnedIoContext; - asio::io_context& m_IoContext; - std::unique_ptr<asio::io_context::work> m_WorkGuard; - std::thread m_IoThread; + std::unique_ptr<asio::io_context> m_OwnedIoContext; + asio::io_context& m_IoContext; + std::optional<asio::executor_work_guard<asio::io_context::executor_type>> m_WorkGuard; + std::thread m_IoThread; // Connection state std::unique_ptr<asio::ip::tcp::resolver> m_Resolver; diff --git a/src/zenhttp/servers/httpasio.cpp b/src/zenhttp/servers/httpasio.cpp index ee8e71256..e8b27da70 100644 --- a/src/zenhttp/servers/httpasio.cpp +++ b/src/zenhttp/servers/httpasio.cpp @@ -530,9 +530,9 @@ public: int GetEffectiveHttpsPort() const; - asio::io_service m_IoService; - asio::io_service::work m_Work{m_IoService}; - std::unique_ptr<asio_http::HttpAcceptor> m_Acceptor; + asio::io_context m_IoService; + asio::executor_work_guard<asio::io_context::executor_type> m_Work{m_IoService.get_executor()}; + std::unique_ptr<asio_http::HttpAcceptor> m_Acceptor; #if defined(ASIO_HAS_LOCAL_SOCKETS) std::unique_ptr<asio_http::UnixAcceptor> m_UnixAcceptor; #endif @@ -1507,7 +1507,7 @@ HttpServerConnectionT<SocketType>::HandleRequest() struct TcpAcceptorBase { TcpAcceptorBase(HttpAsioServerImpl& Server, - asio::io_service& IoService, + asio::io_context& IoService, uint16_t BasePort, bool ForceLoopback, bool AllowPortProbing, @@ -1580,7 +1580,7 @@ protected: virtual void OnAccept(std::unique_ptr<asio::ip::tcp::socket> Socket) = 0; HttpAsioServerImpl& m_Server; - asio::io_service& m_IoService; + asio::io_context& m_IoService; private: template<typename AddressType> @@ -1785,7 +1785,7 @@ private: struct HttpAcceptor final : TcpAcceptorBase { - HttpAcceptor(HttpAsioServerImpl& Server, asio::io_service& IoService, uint16_t BasePort, bool ForceLoopback, bool AllowPortProbing) + HttpAcceptor(HttpAsioServerImpl& Server, asio::io_context& IoService, uint16_t BasePort, bool ForceLoopback, bool AllowPortProbing) : TcpAcceptorBase(Server, IoService, BasePort, ForceLoopback, AllowPortProbing, "HTTP") { } @@ -1810,7 +1810,7 @@ protected: struct UnixAcceptor { - UnixAcceptor(HttpAsioServerImpl& Server, asio::io_service& IoService, const std::string& SocketPath) + UnixAcceptor(HttpAsioServerImpl& Server, asio::io_context& IoService, const std::string& SocketPath) : m_Server(Server) , m_IoService(IoService) , m_Acceptor(m_IoService) @@ -1897,7 +1897,7 @@ private: } HttpAsioServerImpl& m_Server; - asio::io_service& m_IoService; + asio::io_context& m_IoService; asio::local::stream_protocol::acceptor m_Acceptor; std::string m_SocketPath; bool m_IsValid{false}; @@ -1913,7 +1913,7 @@ private: struct HttpsAcceptor final : TcpAcceptorBase { HttpsAcceptor(HttpAsioServerImpl& Server, - asio::io_service& IoService, + asio::io_context& IoService, asio::ssl::context& SslContext, uint16_t Port, bool ForceLoopback, @@ -2284,7 +2284,7 @@ HttpAsioServerImpl::Stop() // Drain remaining handlers (e.g. cancellation callbacks from active WebSocket // connections) so that their captured Ref<> pointers are released while the - // io_service and its epoll reactor are still alive. Without this, sockets + // io_context and its epoll reactor are still alive. Without this, sockets // held by external code (e.g. IWebSocketHandler connection lists) can outlive // the reactor and crash during deregistration. m_IoService.restart(); @@ -2486,9 +2486,9 @@ HttpAsioServer::OnGetExternalHost() const // causes the OS to select the appropriate local interface without sending any data. try { - asio::io_service IoService; + asio::io_context IoService; asio::ip::udp::socket Sock(IoService, asio::ip::udp::v4()); - Sock.connect(asio::ip::udp::endpoint(asio::ip::address::from_string("8.8.8.8"), 80)); + Sock.connect(asio::ip::udp::endpoint(asio::ip::make_address("8.8.8.8"), 80)); return Sock.local_endpoint().address().to_string(); } catch (const std::exception&) diff --git a/src/zenhttp/servers/httpsys.cpp b/src/zenhttp/servers/httpsys.cpp index 83b98013e..4d6a53696 100644 --- a/src/zenhttp/servers/httpsys.cpp +++ b/src/zenhttp/servers/httpsys.cpp @@ -2758,9 +2758,9 @@ HttpSysServer::OnGetExternalHost() const // causes the OS to select the appropriate local interface without sending any data. try { - asio::io_service IoService; + asio::io_context IoService; asio::ip::udp::socket Sock(IoService, asio::ip::udp::v4()); - Sock.connect(asio::ip::udp::endpoint(asio::ip::address::from_string("8.8.8.8"), 80)); + Sock.connect(asio::ip::udp::endpoint(asio::ip::make_address("8.8.8.8"), 80)); return Sock.local_endpoint().address().to_string(); } catch (const std::exception&) diff --git a/src/zenhttp/servers/wstest.cpp b/src/zenhttp/servers/wstest.cpp index 042afd8ff..59c46a418 100644 --- a/src/zenhttp/servers/wstest.cpp +++ b/src/zenhttp/servers/wstest.cpp @@ -508,7 +508,7 @@ TEST_CASE("websocket.integration") { asio::io_context IoCtx; asio::ip::tcp::socket Sock(IoCtx); - Sock.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sock.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); bool Ok = DoWebSocketHandshake(Sock, "/wstest/ws", Port); CHECK(Ok); @@ -523,7 +523,7 @@ TEST_CASE("websocket.integration") { asio::io_context IoCtx; asio::ip::tcp::socket Sock(IoCtx); - Sock.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sock.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); // Send a normal HTTP GET (not upgrade) std::string HttpReq = fmt::format( @@ -547,7 +547,7 @@ TEST_CASE("websocket.integration") { asio::io_context IoCtx; asio::ip::tcp::socket Sock(IoCtx); - Sock.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sock.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); bool Ok = DoWebSocketHandshake(Sock, "/wstest/ws", Port); REQUIRE(Ok); @@ -573,7 +573,7 @@ TEST_CASE("websocket.integration") { asio::io_context IoCtx; asio::ip::tcp::socket Sock(IoCtx); - Sock.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sock.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); bool Ok = DoWebSocketHandshake(Sock, "/wstest/ws", Port); REQUIRE(Ok); @@ -595,7 +595,7 @@ TEST_CASE("websocket.integration") { asio::io_context IoCtx; asio::ip::tcp::socket Sock(IoCtx); - Sock.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sock.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); bool Ok = DoWebSocketHandshake(Sock, "/wstest/ws", Port); REQUIRE(Ok); @@ -627,7 +627,7 @@ TEST_CASE("websocket.integration") for (int i = 0; i < NumClients; ++i) { Sockets.emplace_back(IoCtx); - Sockets.back().connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sockets.back().connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); bool Ok = DoWebSocketHandshake(Sockets.back(), "/wstest/ws", Port); REQUIRE(Ok); @@ -672,7 +672,7 @@ TEST_CASE("websocket.integration") asio::io_context IoCtx; asio::ip::tcp::socket Sock(IoCtx); - Sock.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sock.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); // Attempt WebSocket upgrade on the plain service ExtendableStringBuilder<512> Request; @@ -702,7 +702,7 @@ TEST_CASE("websocket.integration") { asio::io_context IoCtx; asio::ip::tcp::socket Sock(IoCtx); - Sock.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sock.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); bool Ok = DoWebSocketHandshake(Sock, "/wstest/ws", Port); REQUIRE(Ok); @@ -729,7 +729,7 @@ TEST_CASE("websocket.integration") { asio::io_context IoCtx; asio::ip::tcp::socket Sock(IoCtx); - Sock.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), static_cast<uint16_t>(Port))); + Sock.connect(asio::ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), static_cast<uint16_t>(Port))); bool Ok = DoWebSocketHandshake(Sock, "/wstest/ws", Port); REQUIRE(Ok); diff --git a/src/zenhttp/transports/asiotransport.cpp b/src/zenhttp/transports/asiotransport.cpp index 23ac1bc8b..d5413b9af 100644 --- a/src/zenhttp/transports/asiotransport.cpp +++ b/src/zenhttp/transports/asiotransport.cpp @@ -47,10 +47,10 @@ private: uint16_t m_BasePort = 8558; int m_ThreadCount = 0; - asio::io_service m_IoService; - asio::io_service::work m_Work{m_IoService}; - std::unique_ptr<AsioTransportAcceptor> m_Acceptor; - std::vector<std::thread> m_ThreadPool; + asio::io_context m_IoService; + asio::executor_work_guard<asio::io_context::executor_type> m_Work{m_IoService.get_executor()}; + std::unique_ptr<AsioTransportAcceptor> m_Acceptor; + std::vector<std::thread> m_ThreadPool; }; struct AsioTransportConnection : public TransportConnection, std::enable_shared_from_this<AsioTransportConnection> @@ -85,7 +85,7 @@ private: struct AsioTransportAcceptor { - AsioTransportAcceptor(TransportServer* ServerInterface, asio::io_service& IoService, uint16_t BasePort); + AsioTransportAcceptor(TransportServer* ServerInterface, asio::io_context& IoService, uint16_t BasePort); ~AsioTransportAcceptor(); void Start(); @@ -95,7 +95,7 @@ struct AsioTransportAcceptor private: TransportServer* m_ServerInterface = nullptr; - asio::io_service& m_IoService; + asio::io_context& m_IoService; asio::ip::tcp::acceptor m_Acceptor; std::atomic<bool> m_IsStopped{false}; @@ -104,7 +104,7 @@ private: ////////////////////////////////////////////////////////////////////////// -AsioTransportAcceptor::AsioTransportAcceptor(TransportServer* ServerInterface, asio::io_service& IoService, uint16_t BasePort) +AsioTransportAcceptor::AsioTransportAcceptor(TransportServer* ServerInterface, asio::io_context& IoService, uint16_t BasePort) : m_ServerInterface(ServerInterface) , m_IoService(IoService) , m_Acceptor(m_IoService, asio::ip::tcp::v6()) diff --git a/src/zennet/statsdclient.cpp b/src/zennet/statsdclient.cpp index 8afa2e835..9a8aae348 100644 --- a/src/zennet/statsdclient.cpp +++ b/src/zennet/statsdclient.cpp @@ -43,7 +43,7 @@ public: } private: - asio::io_service m_IoService; + asio::io_context m_IoService; std::string m_TargetHost; uint16_t m_TargetPort; @@ -68,9 +68,8 @@ StatsdUdpClient::InitializeSocket() return m_Socket.reset(); } - udp::resolver DnsResolver(m_IoService); - udp::resolver::query DnsQuery(udp::v4(), m_TargetHost, fmt::format("{}", m_TargetPort)); - udp::resolver::iterator It = DnsResolver.resolve(DnsQuery, Ec); + udp::resolver DnsResolver(m_IoService); + udp::resolver::results_type Results = DnsResolver.resolve(udp::v4(), m_TargetHost, fmt::format("{}", m_TargetPort), Ec); if (Ec) { @@ -79,7 +78,7 @@ StatsdUdpClient::InitializeSocket() return m_Socket.reset(); } - m_ServerAddr = *It; + m_ServerAddr = *Results.begin(); } void |