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
This commit is contained in:
Stephen Wilson 2011-01-12 04:22:54 +00:00
parent c2204398e0
commit a08cfb1299
1 changed files with 5 additions and 4 deletions

View File

@ -138,7 +138,7 @@ Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connectio
timeout_usec, timeout_usec,
m_connection_sp.get()); 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 // We have a dedicated read thread that is getting data for us
size_t cached_bytes = GetCachedBytes (dst, dst_len); size_t cached_bytes = GetCachedBytes (dst, dst_len);
@ -257,8 +257,9 @@ Communication::StopReadThread (Error *error_ptr)
Host::ThreadCancel (m_read_thread, 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; m_read_thread = LLDB_INVALID_HOST_THREAD;
return status;
} }
@ -317,7 +318,7 @@ Communication::ReadFromConnection (void *dst, size_t dst_len, ConnectionStatus &
bool bool
Communication::ReadThreadIsRunning () Communication::ReadThreadIsRunning ()
{ {
return m_read_thread != LLDB_INVALID_HOST_THREAD; return m_read_thread_enabled;
} }
void * void *
@ -370,7 +371,7 @@ Communication::ReadThread (void *p)
// Let clients know that this thread is exiting // Let clients know that this thread is exiting
comm->BroadcastEvent (eBroadcastBitReadThreadDidExit); comm->BroadcastEvent (eBroadcastBitReadThreadDidExit);
comm->m_read_thread = LLDB_INVALID_HOST_THREAD; comm->m_read_thread_enabled = false;
comm->Disconnect(); comm->Disconnect();
return NULL; return NULL;
} }