From f9bd1be6dc35273615f6f9968a85c4281d73be89 Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Sat, 10 Feb 2024 16:23:01 +0000 Subject: [PATCH] Return result Messages from Server methods --- .github/workflows/build_and_test.yml | 7 +--- src/IpcServer.cpp | 48 +++++++++++----------------- src/IpcServer.h | 6 ++-- tests/main.cpp | 27 +++++----------- 4 files changed, 32 insertions(+), 56 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index b8dadf3..0027b11 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-11, ubuntu-20.04, windows-2022] + os: [macos-12, ubuntu-20.04, windows-2022] steps: - if: matrix.os == 'windows-2022' @@ -26,11 +26,6 @@ jobs: name: Configure MSVC (Windows) uses: ilammy/msvc-dev-cmd@v1 - - if: matrix.os == 'macos-11' - name: Configure Xcode (MacOS) - run: | - sudo xcode-select -s /Applications/Xcode_11.7.app/Contents/Developer - - name: Configure Python uses: actions/setup-python@v4 with: diff --git a/src/IpcServer.cpp b/src/IpcServer.cpp index c82e7d7..63ce7d9 100644 --- a/src/IpcServer.cpp +++ b/src/IpcServer.cpp @@ -120,12 +120,11 @@ class ServerImpl final #endif } - bool Listen( const std::function& callback ) + Message Listen( const std::function& callback ) { if ( serverSocket == INVALID_SOCKET ) { - callback( Message( "", true ), Message( initError, true ) ); - return false; + return Message( initError, true ); } // Accept a connection @@ -139,17 +138,13 @@ class ServerImpl final if ( select( (int)serverSocket + 1, &fd, nullptr, nullptr, &timeout ) <= 0 ) { - callback( Message( "", true ), - Message( "select() failed (error: " + std::to_string( lastError() ) + ")", true ) ); - return false; + return Message( "select() failed (error: " + std::to_string( lastError() ) + ")", true ); } SOCKET clientSocket = accept( serverSocket, NULL, NULL ); if ( clientSocket == INVALID_SOCKET ) { - callback( Message( "", true ), - Message( "accept() failed (error: " + std::to_string( lastError() ) + ")", true ) ); - return false; + return Message( "accept() failed (error: " + std::to_string( lastError() ) + ")", true ); } #ifdef _WIN32 @@ -167,65 +162,60 @@ class ServerImpl final auto recvHeaderBytes = Receive( clientSocket ); if ( recvHeaderBytes.empty() ) { - if ( lastError() != 0 && lastError() != EINVAL ) + if ( lastError() == 0 || lastError() == EINVAL ) { - callback( Message( "", true ), - Message( "header recv() failed (error: " + std::to_string( lastError() ) + ")", true ) ); + closesocket( clientSocket ); + return Message( "" ); } + closesocket( clientSocket ); - return false; + return Message( "header recv() failed (error: " + std::to_string( lastError() ) + ")", true ); } // Send ack if ( !Send( clientSocket, std::vector{ 1 } ) ) { - callback( Message( "", true ), - Message( "ack send() failed (error: " + std::to_string( lastError() ) + ")", true ) ); closesocket( clientSocket ); - return false; + return Message( "ack send() failed (error: " + std::to_string( lastError() ) + ")", true ); } // Receive message data auto recvMessageBytes = Receive( clientSocket ); if ( recvMessageBytes.empty() ) { - callback( Message( "", true ), - Message( "message recv() failed (error: " + std::to_string( lastError() ) + ")", true ) ); closesocket( clientSocket ); - return false; + return Message( "message recv() failed (error: " + std::to_string( lastError() ) + ")", true ); } // Send some data auto sendMessage = callback( recvHeaderBytes, recvMessageBytes ); if ( !Send( clientSocket, sendMessage ) ) { - callback( Message( "", true ), - Message( "response send() failed (error: " + std::to_string( lastError() ) + ")", true ) ); closesocket( clientSocket ); - return false; + return Message( "response send() failed (error: " + std::to_string( lastError() ) + ")", true ); } closesocket( clientSocket ); - return true; + return Message( "" ); } - bool StopListening() const + Message StopListening() const { SOCKET clientSocket = socket( AF_UNIX, SOCK_STREAM, PF_UNSPEC ); if ( clientSocket == INVALID_SOCKET ) { - return false; + return Message( "socket() failed (error: " + std::to_string( lastError() ) + ")", true ); } if ( connect( clientSocket, reinterpret_cast( &socketAddr ), sizeof( socketAddr ) ) == SOCKET_ERROR ) { closesocket( clientSocket ); - return false; + return Message( "connect() failed (error: " + std::to_string( lastError() ) + ")", true ); } closesocket( clientSocket ); - return true; + return Message( "" ); } static bool Send( SOCKET clientSocket, const Message& message ) @@ -295,12 +285,12 @@ Server::Server( const std::filesystem::path& socketPath ) Server::~Server() = default; -bool Server::Listen( const std::function& callback ) +Message Server::Listen( const std::function& callback ) { return p->Listen( callback ); } -bool Server::StopListening() +Message Server::StopListening() { return p->StopListening(); } diff --git a/src/IpcServer.h b/src/IpcServer.h index 0ba18ea..d886b27 100644 --- a/src/IpcServer.h +++ b/src/IpcServer.h @@ -52,10 +52,12 @@ class Server final Server& operator=( const Server& ) = delete; // Listen() blocks for just one client message, run it in a loop in it's own thread - bool Listen( const std::function& callback ); + // (Use IsError() on the return Message to determine if the call was successful) + Message Listen( const std::function& callback ); // StopListening() should be called from a different thread to Listen() to unblock it - bool StopListening(); + // (Use IsError() on the return Message to determine if the call was successful) + Message StopListening(); private: std::unique_ptr p; diff --git a/tests/main.cpp b/tests/main.cpp index 9f96faf..0265cb7 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -65,8 +65,8 @@ TEST( Ipc, SameProcess ) auto listenThread = std::thread( [&server] { - ASSERT_TRUE( server.Listen( RecvCallback ) ); - ASSERT_TRUE( server.Listen( RecvCallback ) ); + ASSERT_FALSE( server.Listen( RecvCallback ).IsError() ); + ASSERT_FALSE( server.Listen( RecvCallback ).IsError() ); } ); Ipc::Client client( c_serverSocket ); @@ -91,8 +91,8 @@ TEST( Ipc, SeparateProcess ) { Ipc::Server server( c_serverSocket ); ready.set_value(); - ASSERT_TRUE( server.Listen( RecvCallback ) ); - ASSERT_TRUE( server.Listen( RecvCallback ) ); + ASSERT_FALSE( server.Listen( RecvCallback ).IsError() ); + ASSERT_FALSE( server.Listen( RecvCallback ).IsError() ); } ) .detach(); ready.get_future().wait(); @@ -125,7 +125,7 @@ TEST( Ipc, SeparateProcess ) TEST( Ipc, StopListening ) { Ipc::Server server( c_serverSocket ); - auto listenThread = std::thread( [&server] { ASSERT_FALSE( server.Listen( RecvCallback ) ); } ); + auto listenThread = std::thread( [&server] { ASSERT_FALSE( server.Listen( RecvCallback ).IsError() ); } ); server.StopListening(); @@ -141,20 +141,9 @@ TEST( Ipc, PathTooLong ) // Server Ipc::Server server( longPath ); - bool callbackCalled = false; - - ASSERT_FALSE( server.Listen( - [&longPath, &callbackCalled]( const Ipc::Message& header, const Ipc::Message& message ) -> Ipc::Message - { - callbackCalled = true; - EXPECT_TRUE( header.IsError() ); - EXPECT_TRUE( header.AsString().empty() ); - EXPECT_TRUE( message.IsError() ); - EXPECT_EQ( message.AsString(), std::string( "socket path too long: " ) + longPath ); - return Ipc::Message( "" ); - } ) ); - - ASSERT_TRUE( callbackCalled ); + auto result = server.Listen( RecvCallback ); + ASSERT_TRUE( result.IsError() ); + ASSERT_EQ( result.AsString(), std::string( "socket path too long: " ) + longPath ); // Client Ipc::Client client( longPath );