diff options
| author | Stefan Boberg <[email protected]> | 2023-10-13 14:46:49 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-10-13 14:46:49 +0200 |
| commit | c3fad0e98576ff5dee3ee63725459d46e201fa34 (patch) | |
| tree | 91455786fac76ffb6a83ff24620329780ce08545 /src/zenhttp/transports/winsocktransport.cpp | |
| parent | improved http.sys initialization diagnostics and amended logic for dedicated ... (diff) | |
| download | zen-c3fad0e98576ff5dee3ee63725459d46e201fa34.tar.xz zen-c3fad0e98576ff5dee3ee63725459d46e201fa34.zip | |
support for multiple http servers (#473)
* added support for having multiple http servers active in one session
* added configuration API to pluggable transports
* removed pimpl pattern from some pluggable transports implementations
Diffstat (limited to 'src/zenhttp/transports/winsocktransport.cpp')
| -rw-r--r-- | src/zenhttp/transports/winsocktransport.cpp | 163 |
1 files changed, 73 insertions, 90 deletions
diff --git a/src/zenhttp/transports/winsocktransport.cpp b/src/zenhttp/transports/winsocktransport.cpp index ad3302550..2397dd7cf 100644 --- a/src/zenhttp/transports/winsocktransport.cpp +++ b/src/zenhttp/transports/winsocktransport.cpp @@ -20,27 +20,6 @@ ZEN_THIRD_PARTY_INCLUDES_END namespace zen { -class SocketTransportPluginImpl; - -class SocketTransportPlugin : public TransportPlugin, RefCounted -{ -public: - SocketTransportPlugin(uint16_t BasePort, unsigned int ThreadCount); - ~SocketTransportPlugin(); - - virtual uint32_t AddRef() const override; - virtual uint32_t Release() const override; - virtual void Initialize(TransportServer* ServerInterface) override; - virtual void Shutdown() override; - virtual bool IsAvailable() override; - -private: - bool m_IsOk = true; - uint16_t m_BasePort = 0; - int m_ThreadCount = 0; - SocketTransportPluginImpl* m_Impl; -}; - struct SocketTransportConnection : public TransportConnection { public: @@ -172,19 +151,23 @@ SocketTransportConnection::Shutdown(bool Receive, bool Transmit) ////////////////////////////////////////////////////////////////////////// -class SocketTransportPluginImpl +class SocketTransportPluginImpl : public TransportPlugin, RefCounted { public: - SocketTransportPluginImpl(uint16_t BasePort, unsigned int ThreadCount); + SocketTransportPluginImpl(); ~SocketTransportPluginImpl(); - uint16_t Start(uint16_t Port, TransportServer* ServerInterface); - void Stop(); + virtual uint32_t AddRef() const override; + virtual uint32_t Release() const override; + virtual void Configure(const char* OptionTag, const char* OptionValue) override; + virtual void Initialize(TransportServer* ServerInterface) override; + virtual void Shutdown() override; + virtual bool IsAvailable() override; private: TransportServer* m_ServerInterface = nullptr; - uint16_t m_BasePort = 0; - int m_ThreadCount = 0; + uint16_t m_BasePort = 8558; + int m_ThreadCount = 8; bool m_IsOk = true; SOCKET m_ListenSocket{}; @@ -193,9 +176,7 @@ private: std::unique_ptr<WorkerThreadPool> m_WorkerThreadpool; }; -SocketTransportPluginImpl::SocketTransportPluginImpl(uint16_t BasePort, unsigned int ThreadCount) -: m_BasePort(BasePort) -, m_ThreadCount(ThreadCount) +SocketTransportPluginImpl::SocketTransportPluginImpl() { # if ZEN_PLATFORM_WINDOWS WSADATA wsaData; @@ -205,13 +186,11 @@ SocketTransportPluginImpl::SocketTransportPluginImpl(uint16_t BasePort, unsigned WSACleanup(); } # endif - - m_WorkerThreadpool = std::make_unique<WorkerThreadPool>(m_ThreadCount, "http_conn"); } SocketTransportPluginImpl::~SocketTransportPluginImpl() { - Stop(); + Shutdown(); # if ZEN_PLATFORM_WINDOWS if (m_IsOk) @@ -221,36 +200,81 @@ SocketTransportPluginImpl::~SocketTransportPluginImpl() # endif } -uint16_t -SocketTransportPluginImpl::Start(uint16_t Port, TransportServer* ServerInterface) +uint32_t +SocketTransportPluginImpl::AddRef() const +{ + return RefCounted::AddRef(); +} + +uint32_t +SocketTransportPluginImpl::Release() const +{ + return RefCounted::Release(); +} + +void +SocketTransportPluginImpl::Configure(const char* OptionTag, const char* OptionValue) +{ + using namespace std::literals; + + if (OptionTag == "port"sv) + { + if (auto PortNum = ParseInt<uint16_t>(OptionValue)) + { + m_BasePort = *PortNum; + } + } + else if (OptionTag == "threads"sv) + { + if (auto ThreadCount = ParseInt<int>(OptionValue)) + { + m_ThreadCount = *ThreadCount; + } + } + else + { + // Unknown configuration option + } +} + +bool +SocketTransportPluginImpl::IsAvailable() { - m_ServerInterface = ServerInterface; - m_ListenSocket = socket(AF_INET6, SOCK_STREAM, 0); + return true; +} + +void +SocketTransportPluginImpl::Initialize(TransportServer* ServerInterface) +{ + m_ServerInterface = ServerInterface; + m_WorkerThreadpool = std::make_unique<WorkerThreadPool>(m_ThreadCount, "http_conn"); + + m_ListenSocket = socket(AF_INET6, SOCK_STREAM, 0); if (m_ListenSocket == SOCKET_ERROR || m_ListenSocket == INVALID_SOCKET) { ZEN_ERROR("socket creation failed in HTTP plugin server init: {}", WSAGetLastError()); - return 0; + return; } sockaddr_in6 Server{}; Server.sin6_family = AF_INET6; - Server.sin6_port = htons(Port); + Server.sin6_port = htons(m_BasePort); Server.sin6_addr = in6addr_any; if (int Result = bind(m_ListenSocket, (sockaddr*)&Server, sizeof(Server)); Result == SOCKET_ERROR) { ZEN_ERROR("bind call failed in HTTP plugin server init: {}", WSAGetLastError()); - return 0; + return; } if (int Result = listen(m_ListenSocket, AF_INET6); Result == SOCKET_ERROR) { ZEN_ERROR("listen call failed in HTTP plugin server init: {}", WSAGetLastError()); - return 0; + return; } m_KeepRunning.test_and_set(); @@ -292,19 +316,20 @@ SocketTransportPluginImpl::Start(uint16_t Port, TransportServer* ServerInterface ZEN_INFO("HTTP plugin server accept thread exit"); }); - - return Port; } void -SocketTransportPluginImpl::Stop() +SocketTransportPluginImpl::Shutdown() { // TODO: all pending/ongoing work should be drained here as well m_KeepRunning.clear(); - closesocket(m_ListenSocket); - m_ListenSocket = 0; + if (m_ListenSocket) + { + closesocket(m_ListenSocket); + m_ListenSocket = 0; + } if (m_AcceptThread.joinable()) { @@ -314,52 +339,10 @@ SocketTransportPluginImpl::Stop() ////////////////////////////////////////////////////////////////////////// -SocketTransportPlugin::SocketTransportPlugin(uint16_t BasePort, unsigned int ThreadCount) -: m_BasePort(BasePort) -, m_ThreadCount(ThreadCount != 0 ? ThreadCount : Max(std::thread::hardware_concurrency(), 8u)) -, m_Impl(new SocketTransportPluginImpl(BasePort, m_ThreadCount)) -{ -} - -SocketTransportPlugin::~SocketTransportPlugin() -{ - delete m_Impl; -} - -uint32_t -SocketTransportPlugin::AddRef() const -{ - return RefCounted::AddRef(); -} - -uint32_t -SocketTransportPlugin::Release() const -{ - return RefCounted::Release(); -} - -void -SocketTransportPlugin::Initialize(TransportServer* ServerInterface) -{ - m_Impl->Start(m_BasePort, ServerInterface); -} - -void -SocketTransportPlugin::Shutdown() -{ - m_Impl->Stop(); -} - -bool -SocketTransportPlugin::IsAvailable() -{ - return true; -} - TransportPlugin* -CreateSocketTransportPlugin(uint16_t BasePort, unsigned int ThreadCount) +CreateSocketTransportPlugin() { - return new SocketTransportPlugin(BasePort, ThreadCount); + return new SocketTransportPluginImpl; } } // namespace zen |