From 80150dedfbe628162a4109c96378fe3e7ff409df Mon Sep 17 00:00:00 2001
From: Florian Fischer <florian.fl.fischer@fau.de>
Date: Mon, 19 Apr 2021 12:09:32 +0200
Subject: [PATCH] =?UTF-8?q?[EchoServer]=20exit=20the=20echo=20server=20by?=
 =?UTF-8?q?=20terminate=20the=20runtime=20=EF=BF=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since stats are printed in the Runtime destructor we can not simply call
exit() and have to properly terminate the Runtime.
When the echo server receives a "quit" message all active connections will
return and the Runtime will terminate if there is no work left.
---
 apps/EchoServer.cpp | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/apps/EchoServer.cpp b/apps/EchoServer.cpp
index 683b9265..e814b4a5 100644
--- a/apps/EchoServer.cpp
+++ b/apps/EchoServer.cpp
@@ -3,6 +3,7 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 
+#include <atomic>
 #include <cerrno>
 #include <chrono>
 #include <cstdlib>
@@ -25,6 +26,8 @@ const std::string PORT = "12345";
 
 unsigned int computations_us = 0;
 
+std::atomic<bool> quit = false;
+
 auto main(int argc, char* argv[]) -> int {
 	std::string host = HOST;
 	std::string port = PORT;
@@ -48,21 +51,20 @@ auto main(int argc, char* argv[]) -> int {
 	auto* listener = emper::io::tcp_listener(host, port, [](int socket) {
 		// NOLINTNEXTLINE(modernize-avoid-c-arrays)
 		char buf[1024];
-		for (;;) {
+		while (!quit.load(std::memory_order_consume)) {
 			ssize_t bytes_recv = emper::io::recvAndWait(socket, buf, sizeof(buf), 0);
 			if (unlikely(bytes_recv <= 0)) {
 				// socket was shutdown
 				if (bytes_recv < 0) {
 					LOGE("server read failed:" << strerror(errno));
 				}
-
-			finish:
-				emper::io::closeAndForget(socket);
-				return;
 			}
+			break;
 
 			if (unlikely(bytes_recv == 5 && strncmp("quit\n", buf, bytes_recv) == 0)) {
-				exit(EXIT_SUCCESS);
+				quit = true;
+				Runtime::getRuntime()->initiateTermination();
+				break;
 			}
 
 			const auto start = std::chrono::steady_clock::now();
@@ -76,9 +78,11 @@ auto main(int argc, char* argv[]) -> int {
 			ssize_t bytes_send = emper::io::sendAndWait(socket, buf, bytes_recv, MSG_NOSIGNAL, true);
 			if (unlikely(bytes_recv != bytes_send)) {
 				LOGE("server send failed: " << strerror(errno));
-				goto finish;
+				break;
 			}
 		}
+
+		emper::io::closeAndForget(socket);
 	});
 
 	if (!listener) {
-- 
GitLab