From a08cfb1299c33b61474eaba9ad7aef75c2168a66 Mon Sep 17 00:00:00 2001 From: Stephen Wilson Date: Wed, 12 Jan 2011 04:22:54 +0000 Subject: [PATCH] Do not pass an invalid thread to Thread{Cancel,Join}. A race condition exists between StopReadThread and the reader thread proper. When StopReadThread sets m_read_thread_enabled to false the reader thread can terminate and set m_read_thread to LLDB_INVALID_HOST_THREAD on exit. Thus calls to ThreadCancel or ThreadJoin in StopReadThread can be passed an invalid handle. This patch removes the race by using m_read_thread_enabled as the flag thru which the reader thread can notify the parent thread of early/abnormal termination. llvm-svn: 123309 --- lldb/source/Core/Communication.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lldb/source/Core/Communication.cpp b/lldb/source/Core/Communication.cpp index 99c619da606c..b17865738f59 100644 --- a/lldb/source/Core/Communication.cpp +++ b/lldb/source/Core/Communication.cpp @@ -138,7 +138,7 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio timeout_usec, m_connection_sp.get()); - if (m_read_thread != LLDB_INVALID_HOST_THREAD) + if (m_read_thread_enabled) { // We have a dedicated read thread that is getting data for us size_t cached_bytes = GetCachedBytes (dst, dst_len); @@ -257,8 +257,9 @@ Communication::StopReadThread (Error *error_ptr) Host::ThreadCancel (m_read_thread, error_ptr); - return Host::ThreadJoin (m_read_thread, NULL, error_ptr); + bool status = Host::ThreadJoin (m_read_thread, NULL, error_ptr); m_read_thread = LLDB_INVALID_HOST_THREAD; + return status; } @@ -317,7 +318,7 @@ Communication::ReadFromConnection (void *dst, size_t dst_len, ConnectionStatus & bool Communication::ReadThreadIsRunning () { - return m_read_thread != LLDB_INVALID_HOST_THREAD; + return m_read_thread_enabled; } void * @@ -370,7 +371,7 @@ Communication::ReadThread (void *p) // Let clients know that this thread is exiting comm->BroadcastEvent (eBroadcastBitReadThreadDidExit); - comm->m_read_thread = LLDB_INVALID_HOST_THREAD; + comm->m_read_thread_enabled = false; comm->Disconnect(); return NULL; }