diff options
author | Andrii Kalinich (GitHub) <AKalinich@luxoft.com> | 2021-11-09 09:45:29 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-09 09:45:29 -0500 |
commit | 18095c1be36c318200aa7a67c86e66bc021862af (patch) | |
tree | c1a0f725e462151476febb2cf1eae329c75c5844 /src/components | |
parent | 3ca6d944a42d6abf96be9a4a5265e69498091918 (diff) | |
download | sdl_core-18095c1be36c318200aa7a67c86e66bc021862af.tar.gz |
Fix ThreadedSocket disconnect logic (#3566)
* Fix ThreadedSocket disconnect logic
There was noticed an issue with ThreadedSocket connection
which often closes connection like an "unexpected disconnect"
calling `ConnectionAborted()` every time even if it is handled
disconnect. Also, there were no any events raised to Transport
Manager for rare cases when disconnect is expected.
To fix that, flow has been separated for handling expected and
unexpected disconnect. Expected disconnect will be handled in
case when external component calls `Disconnect()` and socket
thread is alive. In that case should be called `DisconnectDone()`
when thread is stopped.
Unexpected disconnect will be handled in case when internal thread
has been aborted and `Abort()` was called. In that case internal
thread `ConnectionAborted()` will be called from internal thread
to notify Transport Manager that physical disconnect has happened.
This issue is pretty hard to detect just because business logic
handles both disconnect types in the same way for now, but this
might be changed in the future.
* Update Boost Download URL
Co-authored-by: JackLivio <jack@livio.io>
Diffstat (limited to 'src/components')
2 files changed, 46 insertions, 25 deletions
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h b/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h index 7c4e07fa59..9241d9e1db 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h @@ -189,7 +189,9 @@ class ThreadedSocketConnection : public Connection { int write_fd_; void threadMain(); void Transmit(); - void Finalize(); + void FinalizeExpectedDisconnect(); + void FinalizeUnexpectedDisconnect(); + void NotifyAboutAbortedMessages(); TransportAdapter::Error Notify() const; bool Receive(); bool Send(); diff --git a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc index 61562d88c0..03e0869180 100644 --- a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc +++ b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc @@ -81,7 +81,8 @@ ThreadedSocketConnection::~ThreadedSocketConnection() { } void ThreadedSocketConnection::StopAndJoinThread() { - Disconnect(); + SDL_LOG_AUTO_TRACE(); + terminate_flag_ = true; if (thread_) { thread_->Stop(threads::Thread::kThreadSoftStop); delete thread_->GetDelegate(); @@ -92,8 +93,10 @@ void ThreadedSocketConnection::StopAndJoinThread() { void ThreadedSocketConnection::Abort() { SDL_LOG_AUTO_TRACE(); - unexpected_disconnect_ = true; - terminate_flag_ = true; + if (!terminate_flag_) { + unexpected_disconnect_ = true; + terminate_flag_ = true; + } } TransportAdapter::Error ThreadedSocketConnection::Start() { @@ -123,18 +126,33 @@ TransportAdapter::Error ThreadedSocketConnection::Start() { return TransportAdapter::OK; } -void ThreadedSocketConnection::Finalize() { - SDL_LOG_AUTO_TRACE(); - if (unexpected_disconnect_) { - SDL_LOG_DEBUG("unexpected_disconnect"); - controller_->ConnectionAborted( - device_handle(), application_handle(), CommunicationError()); - } else { - SDL_LOG_DEBUG("not unexpected_disconnect"); - controller_->ConnectionFinished(device_handle(), application_handle()); +void ThreadedSocketConnection::NotifyAboutAbortedMessages() { + sync_primitives::AutoLock auto_lock(frames_to_send_mutex_); + while (!frames_to_send_.empty()) { + SDL_LOG_INFO("removing message"); + ::protocol_handler::RawMessagePtr message = frames_to_send_.front(); + frames_to_send_.pop(); + controller_->DataSendFailed( + device_handle(), application_handle(), message, DataSendError()); } +} + +void ThreadedSocketConnection::FinalizeUnexpectedDisconnect() { + SDL_LOG_DEBUG("Finalizing unexpected disconnect"); + controller_->ConnectionAborted( + device_handle(), application_handle(), CommunicationError()); + + ShutdownAndCloseSocket(); + NotifyAboutAbortedMessages(); +} + +void ThreadedSocketConnection::FinalizeExpectedDisconnect() { + SDL_LOG_DEBUG("Finalizing expected disconnect"); + controller_->ConnectionFinished(device_handle(), application_handle()); ShutdownAndCloseSocket(); + NotifyAboutAbortedMessages(); + controller_->DisconnectDone(device_handle(), application_handle()); } TransportAdapter::Error ThreadedSocketConnection::Notify() const { @@ -164,9 +182,14 @@ TransportAdapter::Error ThreadedSocketConnection::SendData( TransportAdapter::Error ThreadedSocketConnection::Disconnect() { SDL_LOG_AUTO_TRACE(); - terminate_flag_ = true; - ShutdownAndCloseSocket(); - return Notify(); + + if (!unexpected_disconnect_) { + terminate_flag_ = true; + FinalizeExpectedDisconnect(); + return TransportAdapter::OK; + } + + return TransportAdapter::FAIL; } void ThreadedSocketConnection::Terminate() { @@ -189,16 +212,12 @@ void ThreadedSocketConnection::threadMain() { while (!terminate_flag_) { Transmit(); } - SDL_LOG_DEBUG("Connection is to finalize"); - Finalize(); - sync_primitives::AutoLock auto_lock(frames_to_send_mutex_); - while (!frames_to_send_.empty()) { - SDL_LOG_INFO("removing message"); - ::protocol_handler::RawMessagePtr message = frames_to_send_.front(); - frames_to_send_.pop(); - controller_->DataSendFailed( - device_handle(), application_handle(), message, DataSendError()); + + if (unexpected_disconnect_) { + FinalizeUnexpectedDisconnect(); } + + SDL_LOG_ERROR("Socket connection thread is closed"); } bool ThreadedSocketConnection::IsFramesToSendQueueEmpty() const { |