diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index d337a71262f2..753d4c409fba 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -18,6 +18,7 @@ #include #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 m_command_interpreter_ap; - Mutex m_input_readers_mutex; - std::stack m_input_readers; + InputReaderStack m_input_reader_stack; std::string m_input_reader_data; private: diff --git a/lldb/include/lldb/Core/InputReaderStack.h b/lldb/include/lldb/Core/InputReaderStack.h new file mode 100644 index 000000000000..a73b97cad571 --- /dev/null +++ b/lldb/include/lldb/Core/InputReaderStack.h @@ -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 + +#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 m_input_readers; + mutable Mutex m_input_readers_mutex; + +private: + + DISALLOW_COPY_AND_ASSIGN (InputReaderStack); +}; + +} // namespace lldb_private + +#endif // liblldb_InputReaderStack_h_ diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 6679beaa2421..9f6be9cea23c 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -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 = ""; }; 9A9831091125FC5800A56CB0 /* SBThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBThread.cpp; path = source/API/SBThread.cpp; sourceTree = ""; }; 9A98310A1125FC5800A56CB0 /* SBThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBThread.h; path = include/lldb/API/SBThread.h; sourceTree = ""; }; + 9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReaderStack.cpp; path = source/Core/InputReaderStack.cpp; sourceTree = ""; }; + 9A9E1F0013980943005AC039 /* InputReaderStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InputReaderStack.h; path = include/lldb/Core/InputReaderStack.h; sourceTree = ""; }; 9AA69DAE118A023300D753A0 /* SBInputReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBInputReader.h; path = include/lldb/API/SBInputReader.h; sourceTree = ""; }; 9AA69DB0118A024600D753A0 /* SBInputReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBInputReader.cpp; path = source/API/SBInputReader.cpp; sourceTree = ""; }; 9AA69DB5118A027A00D753A0 /* InputReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReader.cpp; path = source/Core/InputReader.cpp; sourceTree = ""; }; @@ -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; }; diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 80035363650e..ace2c9a54f90 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -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()) { diff --git a/lldb/source/Core/InputReaderStack.cpp b/lldb/source/Core/InputReaderStack.cpp new file mode 100644 index 000000000000..764ea26550f7 --- /dev/null +++ b/lldb/source/Core/InputReaderStack.cpp @@ -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; +}