diff options
Diffstat (limited to 'src/zenhttp/servers/httpsys.cpp')
| -rw-r--r-- | src/zenhttp/servers/httpsys.cpp | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/src/zenhttp/servers/httpsys.cpp b/src/zenhttp/servers/httpsys.cpp index f8fb1c9be..2074fbd79 100644 --- a/src/zenhttp/servers/httpsys.cpp +++ b/src/zenhttp/servers/httpsys.cpp @@ -145,6 +145,7 @@ private: bool m_IsAsyncResponseEnabled = true; std::unique_ptr<WinIoThreadPool> m_IoThreadPool; + bool m_IoThreadPoolIsWinTp = true; RwLock m_AsyncWorkPoolInitLock; std::atomic<WorkerThreadPool*> m_AsyncWorkPool = nullptr; @@ -403,7 +404,8 @@ public: void IssueInitialRequest(std::error_code& ErrorCode); bool IssueNextRequest(HttpSysRequestHandler* NewCompletionHandler); - PTP_IO Iocp(); + void StartIo(); + void CancelIo(); HANDLE RequestQueueHandle(); inline OVERLAPPED* Overlapped() { return &m_IoContext.Overlapped; } inline HttpSysServer& Server() { return m_HttpServer; } @@ -646,9 +648,8 @@ HttpMessageResponseRequest::IssueRequest(std::error_code& ErrorCode) ZEN_TRACE_CPU("httpsys::Response::IssueRequest"); HttpSysTransaction& Tx = Transaction(); HTTP_REQUEST* const HttpReq = Tx.HttpRequest(); - PTP_IO const Iocp = Tx.Iocp(); - StartThreadpoolIo(Iocp); + Tx.StartIo(); // Split payload into batches to play well with the underlying API @@ -863,7 +864,7 @@ HttpMessageResponseRequest::IssueRequest(std::error_code& ErrorCode) // An error occurred, no completion will be posted to IOCP - CancelThreadpoolIo(Iocp); + Tx.CancelIo(); // Emit diagnostics @@ -1045,7 +1046,8 @@ HttpSysServer::HttpSysServer(const HttpSysConfig& InConfig) MaxThreadCount *= 2; } - m_IoThreadPool = std::make_unique<WinIoThreadPool>(MinThreadCount, MaxThreadCount); + m_IoThreadPoolIsWinTp = !m_InitialConfig.UseExplicitIoThreadPool; + m_IoThreadPool = WinIoThreadPool::Create(!m_IoThreadPoolIsWinTp, MinThreadCount, MaxThreadCount); if (m_InitialConfig.AsyncWorkThreadCount == 0) { @@ -1062,10 +1064,11 @@ HttpSysServer::HttpSysServer(const HttpSysConfig& InConfig) m_IsHttpInitialized = true; m_IsOk = true; - ZEN_INFO("http.sys server started in {} mode, using {}-{} I/O threads and {} async worker threads", + ZEN_INFO("http.sys server started in {} mode, using {}-{} I/O threads ({}) and {} async worker threads", m_InitialConfig.IsDedicatedServer ? "DEDICATED" : "NORMAL", MinThreadCount, MaxThreadCount, + m_InitialConfig.UseExplicitIoThreadPool ? "explicit IOCP" : "Windows Thread Pool", m_InitialConfig.AsyncWorkThreadCount); } @@ -1664,7 +1667,8 @@ HttpSysServer::WorkPool() if (!m_AsyncWorkPool.load(std::memory_order_relaxed)) { - m_AsyncWorkPool.store(new WorkerThreadPool(m_InitialConfig.AsyncWorkThreadCount, "http_async"), std::memory_order_release); + m_AsyncWorkPool = + new WorkerThreadPool(m_InitialConfig.AsyncWorkThreadCount, "http_async", m_InitialConfig.UseExplicitIoThreadPool); } } @@ -1839,10 +1843,16 @@ HttpSysTransaction::~HttpSysTransaction() { } -PTP_IO -HttpSysTransaction::Iocp() +void +HttpSysTransaction::StartIo() +{ + m_HttpServer.m_IoThreadPool->StartIo(); +} + +void +HttpSysTransaction::CancelIo() { - return m_HttpServer.m_IoThreadPool->Iocp(); + m_HttpServer.m_IoThreadPool->CancelIo(); } HANDLE @@ -1863,7 +1873,6 @@ static std::atomic<int> HttpSysThreadIndex = 0; static void NameCurrentHttpSysThread() { - t_IsHttpSysThreadNamed = true; const int ThreadIndex = ++HttpSysThreadIndex; zen::ExtendableStringBuilder<16> ThreadName; ThreadName << "httpio_" << ThreadIndex; @@ -1880,13 +1889,6 @@ HttpSysTransaction::IoCompletionCallback(PTP_CALLBACK_INSTANCE Instance, { ZEN_UNUSED(Io, Instance); - // Assign names to threads for context - - if (!t_IsHttpSysThreadNamed) - { - NameCurrentHttpSysThread(); - } - // Note that for a given transaction we may be in this completion function on more // than one thread at any given moment. This means we need to be careful about what // happens in here @@ -1909,6 +1911,19 @@ HttpSysTransaction::IoCompletionCallback(PTP_CALLBACK_INSTANCE Instance, HttpSysTransaction* Transaction = CONTAINING_RECORD(IoContext, HttpSysTransaction, m_IoContext); + // Assign names to threads for context (only needed when using Windows' native + // thread pool) + + if (Transaction->Server().m_IoThreadPoolIsWinTp) + { + if (!t_IsHttpSysThreadNamed) + { + t_IsHttpSysThreadNamed = true; + + NameCurrentHttpSysThread(); + } + } + if (Transaction->HandleCompletion(IoResult, NumberOfBytesTransferred) == HttpSysTransaction::Status::kDone) { delete Transaction; @@ -2391,10 +2406,9 @@ InitialRequestHandler::IssueRequest(std::error_code& ErrorCode) ZEN_TRACE_CPU("httpsys::Request::IssueRequest"); HttpSysTransaction& Tx = Transaction(); - PTP_IO Iocp = Tx.Iocp(); HTTP_REQUEST* HttpReq = Tx.HttpRequest(); - StartThreadpoolIo(Iocp); + Tx.StartIo(); ULONG HttpApiResult; @@ -2428,7 +2442,7 @@ InitialRequestHandler::IssueRequest(std::error_code& ErrorCode) if (HttpApiResult != ERROR_IO_PENDING && HttpApiResult != NO_ERROR) { - CancelThreadpoolIo(Iocp); + Tx.CancelIo(); ErrorCode = MakeErrorCode(HttpApiResult); |