@@ -91,7 +91,7 @@ void PABotBase::connect(){
9191 SerialPABotBase::DeviceRequest_seqnum_reset (), nullptr
9292 ).convert <PABB_MSG_ACK_REQUEST>(logger (), response);
9393}
94- void PABotBase::stop (){
94+ void PABotBase::stop (std::string error_message ){
9595 auto scope_check = m_sanitizer.check_scope ();
9696
9797 // Make sure only one thread can get in here.
@@ -100,6 +100,11 @@ void PABotBase::stop(){
100100 return ;
101101 }
102102
103+ if (!error_message.empty ()){
104+ ReadSpinLock lg (m_state_lock);
105+ m_error_message = std::move (error_message);
106+ }
107+
103108 // Wake everyone up.
104109 {
105110 std::lock_guard<std::mutex> lg (m_sleep_lock);
@@ -149,7 +154,8 @@ void PABotBase::wait_for_all_requests(const Cancellable* cancelled){
149154 throw OperationCancelledException ();
150155 }
151156 if (m_state.load (std::memory_order_acquire) != State::RUNNING){
152- throw InvalidConnectionStateException ();
157+ ReadSpinLock lg0 (m_state_lock);
158+ throw InvalidConnectionStateException (m_error_message);
153159 }
154160 {
155161 ReadSpinLock lg1 (m_state_lock, " PABotBase::wait_for_all_requests()" );
@@ -488,8 +494,11 @@ void PABotBase::on_recv_message(BotBaseMessage message){
488494 return ;
489495 }
490496 const pabb_MsgInfoInvalidType* params = (const pabb_MsgInfoInvalidType*)message.body .c_str ();
491- m_error_message = " PABotBase incompatibility. Device does not recognize message type: " + std::to_string (params->type );
492- m_logger.log (m_error_message, COLOR_RED);
497+ {
498+ WriteSpinLock lg (m_state_lock);
499+ m_error_message = " PABotBase incompatibility. Device does not recognize message type: " + std::to_string (params->type );
500+ m_logger.log (m_error_message, COLOR_RED);
501+ }
493502 m_error.store (true , std::memory_order_release);
494503 std::lock_guard<std::mutex> lg0 (m_sleep_lock);
495504 m_cv.notify_all ();
@@ -501,8 +510,11 @@ void PABotBase::on_recv_message(BotBaseMessage message){
501510 }
502511 const pabb_MsgInfoMissedRequest* params = (const pabb_MsgInfoMissedRequest*)message.body .c_str ();
503512 if (params->seqnum == 1 ){
504- m_error_message = " Serial connection has been interrupted." ;
505- m_logger.log (m_error_message, COLOR_RED);
513+ {
514+ WriteSpinLock lg (m_state_lock);
515+ m_error_message = " Serial connection has been interrupted." ;
516+ m_logger.log (m_error_message, COLOR_RED);
517+ }
506518 m_error.store (true , std::memory_order_release);
507519 std::lock_guard<std::mutex> lg0 (m_sleep_lock);
508520 m_cv.notify_all ();
@@ -511,7 +523,10 @@ void PABotBase::on_recv_message(BotBaseMessage message){
511523 }
512524 case PABB_MSG_ERROR_DISCONNECTED:{
513525 m_logger.log (" The console has disconnected the controller." , COLOR_RED);
514- m_error_message = " Disconnected by console." ;
526+ {
527+ WriteSpinLock lg (m_state_lock);
528+ m_error_message = " Disconnected by console." ;
529+ }
515530 m_error.store (true , std::memory_order_release);
516531 std::lock_guard<std::mutex> lg0 (m_sleep_lock);
517532 m_cv.notify_all ();
@@ -630,7 +645,7 @@ uint64_t PABotBase::try_issue_request(
630645
631646 State state = m_state.load (std::memory_order_acquire);
632647 if (state != State::RUNNING){
633- throw InvalidConnectionStateException ();
648+ throw InvalidConnectionStateException (m_error_message );
634649 }
635650 if (m_error.load (std::memory_order_acquire)){
636651 throw ConnectionException (&m_logger, m_error_message);
@@ -710,7 +725,7 @@ uint64_t PABotBase::try_issue_command(
710725
711726 State state = m_state.load (std::memory_order_acquire);
712727 if (state != State::RUNNING){
713- throw InvalidConnectionStateException ();
728+ throw InvalidConnectionStateException (m_error_message );
714729 }
715730 if (m_error.load (std::memory_order_acquire)){
716731 throw ConnectionException (&m_logger, m_error_message);
@@ -803,9 +818,11 @@ uint64_t PABotBase::issue_request(
803818 throw OperationCancelledException ();
804819 }
805820 if (m_state.load (std::memory_order_acquire) != State::RUNNING){
806- throw InvalidConnectionStateException ();
821+ ReadSpinLock lg0 (m_state_lock);
822+ throw InvalidConnectionStateException (m_error_message);
807823 }
808824 if (m_error.load (std::memory_order_acquire)){
825+ ReadSpinLock lg0 (m_state_lock);
809826 throw ConnectionException (&m_logger, m_error_message);
810827 }
811828 m_cv.wait (lg);
@@ -846,9 +863,11 @@ uint64_t PABotBase::issue_command(
846863 throw OperationCancelledException ();
847864 }
848865 if (m_state.load (std::memory_order_acquire) != State::RUNNING){
849- throw InvalidConnectionStateException ();
866+ ReadSpinLock lg0 (m_state_lock);
867+ throw InvalidConnectionStateException (m_error_message);
850868 }
851869 if (m_error.load (std::memory_order_acquire)){
870+ ReadSpinLock lg0 (m_state_lock);
852871 throw ConnectionException (&m_logger, m_error_message);
853872 }
854873 m_cv.wait (lg);
@@ -914,7 +933,7 @@ BotBaseMessage PABotBase::wait_for_request(uint64_t seqnum, const Cancellable* c
914933 if (state != State::RUNNING){
915934 m_pending_requests.erase (iter);
916935 m_cv.notify_all ();
917- throw InvalidConnectionStateException ();
936+ throw InvalidConnectionStateException (m_error_message );
918937 }
919938 if (m_error.load (std::memory_order_acquire)){
920939 m_pending_requests.erase (iter);
0 commit comments