From da6c0e6194578538ce0bcd1b9815696b96153f6b Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 7 Jun 2021 14:05:51 +0800 Subject: import(life): ... --- works/life/computer-network-experiment/Common.cpp | 19 +++++----- works/life/computer-network-experiment/Common.h | 4 ++- works/life/computer-network-experiment/Output.cpp | 43 ++++++++++++++++++----- works/life/computer-network-experiment/Output.h | 6 ++++ works/life/computer-network-experiment/client.cpp | 4 +-- works/life/computer-network-experiment/server.cpp | 12 +++---- 6 files changed, 62 insertions(+), 26 deletions(-) (limited to 'works') diff --git a/works/life/computer-network-experiment/Common.cpp b/works/life/computer-network-experiment/Common.cpp index 59c2f0f..fbdb2c8 100644 --- a/works/life/computer-network-experiment/Common.cpp +++ b/works/life/computer-network-experiment/Common.cpp @@ -34,9 +34,7 @@ #endif } -#ifdef WIN32 - WSACleanup(); -#endif + BeforeExit(); std::exit(1); } @@ -51,7 +49,7 @@ void InitWSA() { } #endif -int Close(int socket) { +int CloseSocket(int socket) { #ifdef WIN32 return closesocket(socket); #else @@ -59,16 +57,21 @@ int Close(int socket) { #endif } -int main() { +void BeforeExit() { #ifdef WIN32 - InitWSA(); + WSACleanup(); #endif - int c = Main(); + SignalAndWaitForOutputThreadStop(); +} +int main() { #ifdef WIN32 - WSACleanup(); + InitWSA(); #endif + int c = Main(); + + BeforeExit(); return c; } diff --git a/works/life/computer-network-experiment/Common.h b/works/life/computer-network-experiment/Common.h index 4e30439..e5612fd 100644 --- a/works/life/computer-network-experiment/Common.h +++ b/works/life/computer-network-experiment/Common.h @@ -38,4 +38,6 @@ int Main(); void InitWSA(); #endif -int Close(int socket); +int CloseSocket(int socket); + +void BeforeExit(); diff --git a/works/life/computer-network-experiment/Output.cpp b/works/life/computer-network-experiment/Output.cpp index 2968c19..8efb525 100644 --- a/works/life/computer-network-experiment/Output.cpp +++ b/works/life/computer-network-experiment/Output.cpp @@ -1,18 +1,43 @@ #include "Output.h" +#include "folly/CancellationToken.h" folly::MPMCQueue output_queue(100); +folly::CancellationSource cancellation_source; + +std::thread output_thread(OutputThread); + +void PrintOutput(const Output &output) { + switch (output.type) { + case OutputType::Error: + error_stream << output.message; + break; + default: + output_stream << output.message; + break; + } +} + void OutputThread() { while (true) { - Output output; - output_queue.blockingRead(output); - switch (output.type) { - case OutputType::Error: - error_stream << output.message; - break; - default: - output_stream << output.message; - break; + if (cancellation_source.getToken().isCancellationRequested()) { + while (true) { + Output output; + if (output_queue.readIfNotEmpty(output)) { + PrintOutput(output); + } else { + return; + } + } } + + Output output; + if (output_queue.readIfNotEmpty(output)) + PrintOutput(output); } } + +void SignalAndWaitForOutputThreadStop() { + cancellation_source.requestCancellation(); + output_thread.join(); +} diff --git a/works/life/computer-network-experiment/Output.h b/works/life/computer-network-experiment/Output.h index b81dbfd..22b913a 100644 --- a/works/life/computer-network-experiment/Output.h +++ b/works/life/computer-network-experiment/Output.h @@ -5,7 +5,9 @@ #include #include #include +#include +#include #include enum class OutputType { Normal, Error }; @@ -42,3 +44,7 @@ void SendOutput(OutputType type, StringView format, Args &&...args) { } void OutputThread(); + +void SignalAndWaitForOutputThreadStop(); + +extern std::thread output_thread; diff --git a/works/life/computer-network-experiment/client.cpp b/works/life/computer-network-experiment/client.cpp index f209171..5d5075e 100644 --- a/works/life/computer-network-experiment/client.cpp +++ b/works/life/computer-network-experiment/client.cpp @@ -48,8 +48,8 @@ int Main() { std::string s(buffer, received_number); - SendOutput(CRUT("Received message:\n")); + SendOutput(CRUT("Received message:\n{}\n"), ConvertCharString(s)); - Close(client_socket); + CloseSocket(client_socket); return 0; } diff --git a/works/life/computer-network-experiment/server.cpp b/works/life/computer-network-experiment/server.cpp index a5a7a9b..14987f3 100644 --- a/works/life/computer-network-experiment/server.cpp +++ b/works/life/computer-network-experiment/server.cpp @@ -42,22 +42,20 @@ void ResponseThreadProc(int socket, sockaddr_in address) { // send failed if (byte_actually_sent == -1) { SendOutput(OutputType::Error, CRUT("Failed to send!\n")); - Close(socket); + CloseSocket(socket); break; } byte_count_sent += byte_actually_sent; } - SendOutput(CRUT("Succeeded to send message to {} !\n"), + SendOutput(CRUT("Succeeded to send message to {}!\n"), ConvertCharString(address_string)); - Close(socket); + CloseSocket(socket); } int Main() { - std::thread output_thread(OutputThread); - int server_socket; if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { @@ -81,6 +79,8 @@ int Main() { } while (true) { + SendOutput(CRUT("Now start to accept incoming connection.\n")); + sockaddr_in client_address; int client_socket; unsigned sin_size = sizeof(sockaddr_in); @@ -92,7 +92,7 @@ int Main() { (&sin_size)); if (client_socket == -1) { - PrintErrorMessageAndExit(CRUT("Failed to accecpt")); + PrintErrorMessageAndExit(CRUT("Failed to accecpt.")); } std::thread response_thread(ResponseThreadProc, client_socket, -- cgit v1.2.3