From 1b99ceae67794bc3767d4cc7ac70c23b4496f9ef Mon Sep 17 00:00:00 2001 From: Carsten Patzke <carsten.patzke@desy.de> Date: Tue, 13 Mar 2018 16:39:19 +0100 Subject: [PATCH] Added receiver errors --- common/cpp/include/common/error.h | 5 +-- receiver/src/main.cpp | 10 ++++-- receiver/src/network_producer_peer.cpp | 5 ++- receiver/src/receiver.cpp | 30 ++++++---------- receiver/src/receiver.h | 49 +++++++++++++++++++++++--- 5 files changed, 69 insertions(+), 30 deletions(-) diff --git a/common/cpp/include/common/error.h b/common/cpp/include/common/error.h index 0db2fe455..3a0b1918c 100644 --- a/common/cpp/include/common/error.h +++ b/common/cpp/include/common/error.h @@ -13,6 +13,7 @@ enum class ErrorType { kHidraError, kHttpError, kIOError, + kReceiverError, kMemoryAllocationError, kEndOfFile @@ -30,7 +31,7 @@ class ErrorInterface { virtual void Append(const std::string& value) noexcept = 0; virtual ErrorType GetErrorType() const noexcept = 0; virtual ~ErrorInterface() = default; // needed for unique_ptr to delete itself - /*TODO: Add these function, so it will be really easy and convenient to use the error class + /*TODO: Add these functions, so it will be really easy and convenient to use the error class * virtual inline bool operator == (const Error& rhs) const * virtual inline bool operator != (const Error& rhs) const * virtual inline bool operator == (const ErrorTemplateInterface& rhs) const @@ -44,7 +45,7 @@ class ErrorTemplateInterface { public: virtual ErrorType GetErrorType() const noexcept = 0; virtual Error Generate() const noexcept = 0; - /*TODO: Add these function, so it will be really easy and convenient to use the error class + /*TODO: Add these functions, so it will be really easy and convenient to use the error class * virtual inline bool operator ErrorTemplateInterface() const */ diff --git a/receiver/src/main.cpp b/receiver/src/main.cpp index c635f023d..871af6f08 100644 --- a/receiver/src/main.cpp +++ b/receiver/src/main.cpp @@ -6,11 +6,11 @@ int main (int argc, char* argv[]) { auto* receiver = new hidra2::Receiver(); - hidra2::ReceiverError err; + hidra2::Error err; receiver->StartListener(address, &err); - if(err != hidra2::ReceiverError::kNoError) { - std::cerr << "Fail to start receiver" << std::endl; + if(err) { + std::cerr << "Fail to start receiver: " << err->Explain() << std::endl; return 1; } std::cout << "StartListener on " << address << std::endl; @@ -20,6 +20,10 @@ int main (int argc, char* argv[]) { std::cout << "Stop listener..." << std::endl; receiver->StopListener(&err);//TODO might not work since Accept is a blocking call :/ + if(err) { + std::cerr << "Fail to stop receiver: " << err->Explain() << std::endl; + return 1; + } return 0; } diff --git a/receiver/src/network_producer_peer.cpp b/receiver/src/network_producer_peer.cpp index c08f89549..080a07bce 100644 --- a/receiver/src/network_producer_peer.cpp +++ b/receiver/src/network_producer_peer.cpp @@ -51,6 +51,8 @@ void NetworkProducerPeer::internal_receiver_thread_() { } std::cout << "[" << GetConnectionId() << "] Got request: " << generic_request->op_code << std::endl; + + //generic_response will be set here and the amount to send is returned size_t bytes_to_send = handle_generic_request_(generic_request.get(), generic_response.get()); if(bytes_to_send == 0) { @@ -92,7 +94,8 @@ size_t NetworkProducerPeer::handle_generic_request_(GenericNetworkRequest* reque Error io_err; static const size_t sizeof_generic_request = sizeof(GenericNetworkRequest); - //receive the rest of the message + //after receiving all GenericNetworkResponse fields from caller, + //we need now need to receive the rest of the request io->Receive(socket_fd_, (uint8_t*)request + sizeof_generic_request, handler_information.request_size - sizeof_generic_request, &io_err); diff --git a/receiver/src/receiver.cpp b/receiver/src/receiver.cpp index a350bcf7c..e7be0646e 100644 --- a/receiver/src/receiver.cpp +++ b/receiver/src/receiver.cpp @@ -5,41 +5,33 @@ const int hidra2::Receiver::kMaxUnacceptedConnectionsBacklog = 5; -void hidra2::Receiver::StartListener(std::string listener_address, ReceiverError* err) { - *err = ReceiverError::kNoError; +void hidra2::Receiver::StartListener(std::string listener_address, Error* err) { + *err = nullptr; if(listener_running_) { - *err = ReceiverError::kAlreadyListening; + *err = ReceiverErrorTemplates::kAlreadyListening.Generate(); return; } listener_running_ = true; - Error io_error; - FileDescriptor listener_fd = io->CreateSocket(AddressFamilies::INET, SocketTypes::STREAM, SocketProtocols::IP, - &io_error); - if(io_error != nullptr) { - *err = ReceiverError::kFailToCreateSocket; + err); + if(*err) { listener_running_ = false; - std::cerr << "Fail to create socket" << std::endl; return; } - io->InetBind(listener_fd, listener_address, &io_error); - if(io_error != nullptr) { + io->InetBind(listener_fd, listener_address, err); + if(*err) { io->CloseSocket(listener_fd, nullptr); - *err = ReceiverError::kFailToCreateSocket; listener_running_ = false; - std::cerr << "Fail to bind socket" << std::endl; return; } - io->Listen(listener_fd, kMaxUnacceptedConnectionsBacklog, &io_error); - if(io_error != nullptr) { + io->Listen(listener_fd, kMaxUnacceptedConnectionsBacklog, err); + if(*err) { io->CloseSocket(listener_fd, nullptr); - *err = ReceiverError::kFailToCreateSocket; listener_running_ = false; - std::cerr << "Fail to start listen" << std::endl; return; } @@ -58,7 +50,7 @@ void hidra2::Receiver::AcceptThreadLogic() { Error io_error; auto client_info_tuple = io->InetAccept(listener_fd_, &io_error); - if(io_error != nullptr) { + if(io_error) { std::cerr << "An error occurred while accepting an incoming connection" << std::endl; return; } @@ -68,7 +60,7 @@ void hidra2::Receiver::AcceptThreadLogic() { } } -void hidra2::Receiver::StopListener(ReceiverError* err) { +void hidra2::Receiver::StopListener(Error* err) { listener_running_ = false; io->CloseSocket(listener_fd_, nullptr); if(accept_thread_) diff --git a/receiver/src/receiver.h b/receiver/src/receiver.h index f968952cb..8fdf6be54 100644 --- a/receiver/src/receiver.h +++ b/receiver/src/receiver.h @@ -9,10 +9,49 @@ namespace hidra2 { -enum class ReceiverError { - kNoError, +enum class ReceiverErrorType { kAlreadyListening, - kFailToCreateSocket, +}; + +class ReceiverError : public SimpleError { + private: + ReceiverErrorType receiver_error_type_; + public: + ReceiverError(const std::string& error, ReceiverErrorType receiver_error_type) : SimpleError(error, + ErrorType::kReceiverError) { + receiver_error_type_ = receiver_error_type; + } + + ReceiverErrorType GetReceiverErrorType() const noexcept { + return receiver_error_type_; + } +}; + +class ReceiverErrorTemplate : public SimpleErrorTemplate { + protected: + ReceiverErrorType receiver_error_type_; + public: + ReceiverErrorTemplate(const std::string& error, ReceiverErrorType receiver_error_type) : SimpleErrorTemplate(error, + ErrorType::kIOError) { + receiver_error_type_ = receiver_error_type; + } + + inline ReceiverErrorType GetReceiverErrorType() const noexcept { + return receiver_error_type_; + } + + inline Error Generate() const noexcept override { + return Error(new ReceiverError(error_, receiver_error_type_)); + } + + inline bool operator == (const Error& rhs) const override { + return SimpleErrorTemplate::operator==(rhs) + && GetReceiverErrorType() == ((ReceiverError*)rhs.get())->GetReceiverErrorType(); + } +}; + +namespace ReceiverErrorTemplates { +auto const kAlreadyListening = ReceiverErrorTemplate{"Receiver is already listening", ReceiverErrorType::kAlreadyListening}; }; class Receiver : public HasIO { @@ -34,8 +73,8 @@ class Receiver : public HasIO { Receiver() = default; - void StartListener(std::string listener_address, ReceiverError* err); - void StopListener(ReceiverError* err); + void StartListener(std::string listener_address, Error* err); + void StopListener(Error* err); }; } -- GitLab