@@ -93,13 +93,12 @@ class DoIPServer {
9393 */
9494 bool setupTcpSocket ();
9595
96- template <typename Model = DefaultDoIPServerModel>
9796 /* *
9897 * @brief Block until a TCP client connects and create a DoIP connection.
99- * @tparam Model Server model type used by the connection (default `DefaultDoIPServerModel`) .
98+ * @param model Server model instance used by the connection.
10099 * @return Unique pointer to established `DoIPConnection`, or nullptr on failure.
101100 */
102- std::unique_ptr<DoIPConnection> waitForTcpConnection ();
101+ std::unique_ptr<DoIPConnection> waitForTcpConnection (UniqueServerModelPtr model );
103102
104103 [[nodiscard]]
105104 /* *
@@ -238,8 +237,11 @@ class DoIPServer {
238237
239238 ssize_t sendNegativeUdpAck (DoIPNegativeAck ackCode);
240239
241- template <typename Model>
242- void tcpListenerThread ();
240+ /* *
241+ * @brief Background TCP listener that accepts connections and spawns handlers.
242+ * @param modelFactory Factory callable that returns a `UniqueServerModelPtr` per connection.
243+ */
244+ void tcpListenerThread (std::function<UniqueServerModelPtr()> modelFactory);
243245
244246 void connectionHandlerThread (std::unique_ptr<DoIPConnection> connection);
245247
@@ -250,50 +252,6 @@ class DoIPServer {
250252 ssize_t sendUdpResponse (DoIPMessage msg);
251253};
252254
253- // Template implementation must be in header for external linkage
254- template <typename Model>
255- std::unique_ptr<DoIPConnection> DoIPServer::waitForTcpConnection () {
256- static_assert (std::is_default_constructible<Model>::value,
257- " Model must be default-constructible" );
258-
259- // waits till client approach to make connection
260- if (listen (m_tcp_sock, 5 ) < 0 ) {
261- return nullptr ;
262- }
263-
264- int tcpSocket = accept (m_tcp_sock, nullptr , nullptr );
265- if (tcpSocket < 0 ) {
266- return nullptr ;
267- }
268-
269- return std::unique_ptr<DoIPConnection>(new DoIPConnection (tcpSocket, std::make_unique<Model>()));
270- }
271-
272- /*
273- * Background thread: TCP connection acceptor
274- */
275- template <typename Model>
276- void DoIPServer::tcpListenerThread () {
277- LOG_DOIP_INFO (" TCP listener thread started" );
278-
279- while (m_running.load ()) {
280- auto connection = waitForTcpConnection<Model>();
281-
282- if (!connection) {
283- if (m_running.load ()) {
284- LOG_TCP_DEBUG (" Failed to accept connection, retrying..." );
285- std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
286- }
287- continue ;
288- }
289-
290- // Spawn a dedicated thread for this connection
291- // Note: We detach because the connection thread manages its own lifecycle
292- std::thread (&DoIPServer::connectionHandlerThread, this , std::move (connection)).detach ();
293- }
294-
295- LOG_DOIP_INFO (" TCP listener thread stopped" );
296- }
297255
298256} // namespace doip
299257
0 commit comments