* @brief Stops the gRPC server and cancels all active streams. */
| 482 | * @brief Stops the gRPC server and cancels all active streams. |
| 483 | */ |
| 484 | void API::GRPC::GRPCServer::stopServer() |
| 485 | { |
| 486 | { |
| 487 | std::lock_guard<std::mutex> lock(m_frameStreamsMutex); |
| 488 | for (auto& ctx : m_frameStreams) |
| 489 | ctx->cancelled.store(true); |
| 490 | } |
| 491 | |
| 492 | { |
| 493 | std::lock_guard<std::mutex> lock(m_rawStreamsMutex); |
| 494 | for (auto& ctx : m_rawStreams) |
| 495 | ctx->cancelled.store(true); |
| 496 | } |
| 497 | |
| 498 | m_writerRunning.store(false); |
| 499 | if (m_writerThread.joinable()) |
| 500 | m_writerThread.join(); |
| 501 | |
| 502 | if (m_grpcServer) |
| 503 | m_grpcServer->Shutdown(std::chrono::system_clock::now() + std::chrono::seconds(3)); |
| 504 | |
| 505 | if (m_serverThread.joinable()) |
| 506 | m_serverThread.join(); |
| 507 | |
| 508 | m_grpcServer.reset(); |
| 509 | m_service.reset(); |
| 510 | |
| 511 | m_clientCount.store(0, std::memory_order_relaxed); |
| 512 | Q_EMIT clientCountChanged(); |
| 513 | } |
| 514 | |
| 515 | /** |
| 516 | * @brief Writes a RawBatch to every active raw stream, marking unwritable streams cancelled. |