/** * To solve the problem of accept() blocking forever, we are going to use a classic networking trick: * The Alarm Clock (select). Instead of letting accept() sleep forever, we set an alarm clock for 1 second. * If a client calls before the alarm rings, we answer the phone (accept). If the alarm rings first, we wake up, * check our "Stop Sign" (the interrupt flag), and if it's raised, we gracefully shut down. */ #ifndef IOVI_NETWORK_SERVER_SOCKET_THREAD_H #define IOVI_NETWORK_SERVER_SOCKET_THREAD_H #include "../NetworkConfig.h" #include #include #include // For thread-safe "Stop Signs" class ServerSocketThread { SOCKET_TYPE serverSocket; int port; // THE STOP SIGN: std::atomic ensures that when one thread changes this // to 'false', the other thread sees the change instantly, without caching issues. std::atomic running{false}; // THE WORKER: The background thread that will run our server loop. std::thread serverThread; // The actual infinite loop that runs inside the background thread, main server logic void serverLoop() const; // The echo logic (same as before, but now static so the thread can call it) static void handleClient(SOCKET_TYPE clientSocket); public: explicit ServerSocketThread(int p); ~ServerSocketThread(); // Starts the background thread void start(); // Raises the stop sign and waits for the thread to finish cleanly void stop(); // Checks if the server is currently running bool isRunning() const { return running.load(); } }; #endif // IOVI_NETWORK_SERVER_SOCKET_THREAD_H