forked from OSchip/llvm-project
Create new class, InputReaderStack, to better handle
mutexes around input readers and prevent deadlocking; modify Debugger to use the new class. llvm-svn: 132475
This commit is contained in:
parent
9d4a8cf481
commit
d5a0a01b2d
|
@ -18,6 +18,7 @@
|
|||
#include <stack>
|
||||
|
||||
#include "lldb/Core/Communication.h"
|
||||
#include "lldb/Core/InputReaderStack.h"
|
||||
#include "lldb/Core/Listener.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/SourceManager.h"
|
||||
|
@ -451,8 +452,7 @@ protected:
|
|||
SourceManager m_source_manager;
|
||||
std::auto_ptr<CommandInterpreter> m_command_interpreter_ap;
|
||||
|
||||
Mutex m_input_readers_mutex;
|
||||
std::stack<lldb::InputReaderSP> m_input_readers;
|
||||
InputReaderStack m_input_reader_stack;
|
||||
std::string m_input_reader_data;
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
//===-- InputReaderStack.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_InputReaderStack_h_
|
||||
#define liblldb_InputReaderStack_h_
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class InputReaderStack
|
||||
{
|
||||
public:
|
||||
|
||||
InputReaderStack ();
|
||||
|
||||
~InputReaderStack ();
|
||||
|
||||
size_t
|
||||
GetSize () const;
|
||||
|
||||
void
|
||||
Push (const lldb::InputReaderSP& reader_sp);
|
||||
|
||||
bool
|
||||
IsEmpty () const;
|
||||
|
||||
lldb::InputReaderSP
|
||||
Top ();
|
||||
|
||||
void
|
||||
Pop ();
|
||||
|
||||
Mutex &
|
||||
GetStackMutex ();
|
||||
|
||||
protected:
|
||||
|
||||
std::stack<lldb::InputReaderSP> m_input_readers;
|
||||
mutable Mutex m_input_readers_mutex;
|
||||
|
||||
private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (InputReaderStack);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_InputReaderStack_h_
|
|
@ -409,6 +409,8 @@
|
|||
9A3576A8116E9AB700E8ED2F /* SBHostOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3576A7116E9AB700E8ED2F /* SBHostOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9A3576AA116E9AC700E8ED2F /* SBHostOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */; };
|
||||
9A4F35101368A51A00823F52 /* StreamAsynchronousIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */; };
|
||||
9A9E1EFF1398086D005AC039 /* InputReaderStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */; };
|
||||
9A9E1F0113980943005AC039 /* InputReaderStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A9E1F0013980943005AC039 /* InputReaderStack.h */; };
|
||||
9AA69DA61188F52100D753A0 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */; };
|
||||
9AA69DAF118A023300D753A0 /* SBInputReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AA69DAE118A023300D753A0 /* SBInputReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9AA69DB1118A024600D753A0 /* SBInputReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AA69DB0118A024600D753A0 /* SBInputReader.cpp */; };
|
||||
|
@ -1200,6 +1202,8 @@
|
|||
9A9831081125FC5800A56CB0 /* SBTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBTarget.h; path = include/lldb/API/SBTarget.h; sourceTree = "<group>"; };
|
||||
9A9831091125FC5800A56CB0 /* SBThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBThread.cpp; path = source/API/SBThread.cpp; sourceTree = "<group>"; };
|
||||
9A98310A1125FC5800A56CB0 /* SBThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBThread.h; path = include/lldb/API/SBThread.h; sourceTree = "<group>"; };
|
||||
9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReaderStack.cpp; path = source/Core/InputReaderStack.cpp; sourceTree = "<group>"; };
|
||||
9A9E1F0013980943005AC039 /* InputReaderStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InputReaderStack.h; path = include/lldb/Core/InputReaderStack.h; sourceTree = "<group>"; };
|
||||
9AA69DAE118A023300D753A0 /* SBInputReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBInputReader.h; path = include/lldb/API/SBInputReader.h; sourceTree = "<group>"; };
|
||||
9AA69DB0118A024600D753A0 /* SBInputReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBInputReader.cpp; path = source/API/SBInputReader.cpp; sourceTree = "<group>"; };
|
||||
9AA69DB5118A027A00D753A0 /* InputReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReader.cpp; path = source/Core/InputReader.cpp; sourceTree = "<group>"; };
|
||||
|
@ -1889,6 +1893,8 @@
|
|||
26BC7D6410F1B77400F91463 /* Flags.h */,
|
||||
9AA69DBB118A029E00D753A0 /* InputReader.h */,
|
||||
9AA69DB5118A027A00D753A0 /* InputReader.cpp */,
|
||||
9A9E1F0013980943005AC039 /* InputReaderStack.h */,
|
||||
9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */,
|
||||
26BC7D6510F1B77400F91463 /* IOStreamMacros.h */,
|
||||
26BC7D6610F1B77400F91463 /* Language.h */,
|
||||
26BC7E7D10F1B85900F91463 /* Language.cpp */,
|
||||
|
@ -2619,6 +2625,7 @@
|
|||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9A9E1F0113980943005AC039 /* InputReaderStack.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -3201,6 +3208,7 @@
|
|||
26DB3E1F1379E7AD0080DC73 /* ABISysV_x86_64.cpp in Sources */,
|
||||
26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */,
|
||||
2690B3711381D5C300ECFBAE /* Memory.cpp in Sources */,
|
||||
9A9E1EFF1398086D005AC039 /* InputReaderStack.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -230,8 +230,7 @@ Debugger::Debugger () :
|
|||
m_listener ("lldb.Debugger"),
|
||||
m_source_manager (),
|
||||
m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
|
||||
m_input_readers_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_input_readers (),
|
||||
m_input_reader_stack (),
|
||||
m_input_reader_data ()
|
||||
{
|
||||
m_command_interpreter_ap->Initialize ();
|
||||
|
@ -357,14 +356,13 @@ Debugger::GetCurrentInputReader ()
|
|||
{
|
||||
InputReaderSP reader_sp;
|
||||
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
if (!m_input_readers.empty())
|
||||
if (!m_input_reader_stack.IsEmpty())
|
||||
{
|
||||
// Clear any finished readers from the stack
|
||||
while (CheckIfTopInputReaderIsDone()) ;
|
||||
|
||||
if (!m_input_readers.empty())
|
||||
reader_sp = m_input_readers.top();
|
||||
if (!m_input_reader_stack.IsEmpty())
|
||||
reader_sp = m_input_reader_stack.Top();
|
||||
}
|
||||
|
||||
return reader_sp;
|
||||
|
@ -424,9 +422,8 @@ Debugger::CleanUpInputReaders ()
|
|||
{
|
||||
m_input_reader_data.clear();
|
||||
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
// The bottom input reader should be the main debugger input reader. We do not want to close that one here.
|
||||
while (m_input_readers.size() > 1)
|
||||
while (m_input_reader_stack.GetSize() > 1)
|
||||
{
|
||||
InputReaderSP reader_sp (GetCurrentInputReader ());
|
||||
if (reader_sp)
|
||||
|
@ -479,8 +476,7 @@ Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
|
|||
if (m_input_reader_data.empty())
|
||||
return;
|
||||
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
while (!m_input_readers.empty() && !m_input_reader_data.empty())
|
||||
while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
|
||||
{
|
||||
// Get the input reader from the top of the stack
|
||||
InputReaderSP reader_sp (GetCurrentInputReader ());
|
||||
|
@ -519,8 +515,7 @@ Debugger::PushInputReader (const InputReaderSP& reader_sp)
|
|||
if (top_reader_sp)
|
||||
top_reader_sp->Notify (eInputReaderDeactivate);
|
||||
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
m_input_readers.push (reader_sp);
|
||||
m_input_reader_stack.Push (reader_sp);
|
||||
reader_sp->Notify (eInputReaderActivate);
|
||||
ActivateInputReader (reader_sp);
|
||||
}
|
||||
|
@ -532,22 +527,21 @@ Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
|
|||
|
||||
// The reader on the stop of the stack is done, so let the next
|
||||
// read on the stack referesh its prompt and if there is one...
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
if (!m_input_readers.empty())
|
||||
if (!m_input_reader_stack.IsEmpty())
|
||||
{
|
||||
// Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
|
||||
InputReaderSP reader_sp(m_input_readers.top());
|
||||
InputReaderSP reader_sp(m_input_reader_stack.Top());
|
||||
|
||||
if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
|
||||
{
|
||||
m_input_readers.pop ();
|
||||
m_input_reader_stack.Pop ();
|
||||
reader_sp->Notify (eInputReaderDeactivate);
|
||||
reader_sp->Notify (eInputReaderDone);
|
||||
result = true;
|
||||
|
||||
if (!m_input_readers.empty())
|
||||
if (!m_input_reader_stack.IsEmpty())
|
||||
{
|
||||
reader_sp = m_input_readers.top();
|
||||
reader_sp = m_input_reader_stack.Top();
|
||||
if (reader_sp)
|
||||
{
|
||||
ActivateInputReader (reader_sp);
|
||||
|
@ -563,11 +557,10 @@ bool
|
|||
Debugger::CheckIfTopInputReaderIsDone ()
|
||||
{
|
||||
bool result = false;
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
if (!m_input_readers.empty())
|
||||
if (!m_input_reader_stack.IsEmpty())
|
||||
{
|
||||
// Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
|
||||
InputReaderSP reader_sp(m_input_readers.top());
|
||||
InputReaderSP reader_sp(m_input_reader_stack.Top());
|
||||
|
||||
if (reader_sp && reader_sp->IsDone())
|
||||
{
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
//===-- InputReaderStack.cpp ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Core/InputReaderStack.h"
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
InputReaderStack::InputReaderStack () :
|
||||
m_input_readers (),
|
||||
m_input_readers_mutex (Mutex::eMutexTypeRecursive)
|
||||
{
|
||||
}
|
||||
|
||||
InputReaderStack::~InputReaderStack ()
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
InputReaderStack::GetSize () const
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
return m_input_readers.size();
|
||||
}
|
||||
|
||||
void
|
||||
InputReaderStack::Push (const lldb::InputReaderSP& reader_sp)
|
||||
{
|
||||
if (reader_sp)
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
m_input_readers.push (reader_sp);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
InputReaderStack::IsEmpty () const
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
return m_input_readers.empty();
|
||||
}
|
||||
|
||||
InputReaderSP
|
||||
InputReaderStack::Top ()
|
||||
{
|
||||
InputReaderSP input_reader_sp;
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
if (!m_input_readers.empty())
|
||||
input_reader_sp = m_input_readers.top();
|
||||
}
|
||||
|
||||
return input_reader_sp;
|
||||
}
|
||||
|
||||
void
|
||||
InputReaderStack::Pop ()
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
if (!m_input_readers.empty())
|
||||
m_input_readers.pop();
|
||||
}
|
||||
|
||||
Mutex &
|
||||
InputReaderStack::GetStackMutex ()
|
||||
{
|
||||
return m_input_readers_mutex;
|
||||
}
|
Loading…
Reference in New Issue