diff --git a/lldb/include/lldb/Core/ThreadedCommunication.h b/lldb/include/lldb/Core/ThreadedCommunication.h index 2e3afde3c0582..7ebb77beb77f3 100644 --- a/lldb/include/lldb/Core/ThreadedCommunication.h +++ b/lldb/include/lldb/Core/ThreadedCommunication.h @@ -223,10 +223,22 @@ class ThreadedCommunication : public Communication, public Broadcaster { } protected: - HostThread m_read_thread; ///< The read thread handle in case we need to - /// cancel the thread. + /// The read thread handle in case we need to cancel the thread. + /// @{ + HostThread m_read_thread; + std::mutex m_read_thread_mutex; + /// @} + + /// Whether the read thread is enabled. This cannot be guarded by the read + /// thread mutex becuase it is used as the control variable to exit the read + /// thread. std::atomic m_read_thread_enabled; + + /// Whether the read thread is enabled. Technically this could be guarded by + /// the read thread mutex but that needlessly complicates things to + /// check this variables momentary value. std::atomic m_read_thread_did_exit; + std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function. std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded diff --git a/lldb/source/Core/ThreadedCommunication.cpp b/lldb/source/Core/ThreadedCommunication.cpp index 755a158a5359e..7d8aae5d8ff68 100644 --- a/lldb/source/Core/ThreadedCommunication.cpp +++ b/lldb/source/Core/ThreadedCommunication.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -155,6 +156,8 @@ size_t ThreadedCommunication::Read(void *dst, size_t dst_len, } bool ThreadedCommunication::StartReadThread(Status *error_ptr) { + std::lock_guard lock(m_read_thread_mutex); + if (error_ptr) error_ptr->Clear(); @@ -189,6 +192,8 @@ bool ThreadedCommunication::StartReadThread(Status *error_ptr) { } bool ThreadedCommunication::StopReadThread(Status *error_ptr) { + std::lock_guard lock(m_read_thread_mutex); + if (!m_read_thread.IsJoinable()) return true; @@ -199,13 +204,13 @@ bool ThreadedCommunication::StopReadThread(Status *error_ptr) { BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr); - // error = m_read_thread.Cancel(); - Status error = m_read_thread.Join(nullptr); return error.Success(); } bool ThreadedCommunication::JoinReadThread(Status *error_ptr) { + std::lock_guard lock(m_read_thread_mutex); + if (!m_read_thread.IsJoinable()) return true;