aboutsummaryrefslogtreecommitdiff
path: root/src/zenhttp/transports/winsocktransport.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-10-13 14:46:49 +0200
committerGitHub <[email protected]>2023-10-13 14:46:49 +0200
commitc3fad0e98576ff5dee3ee63725459d46e201fa34 (patch)
tree91455786fac76ffb6a83ff24620329780ce08545 /src/zenhttp/transports/winsocktransport.cpp
parentimproved http.sys initialization diagnostics and amended logic for dedicated ... (diff)
downloadzen-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.cpp163
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