summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/common/Editline.cpp
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2015-05-27 12:40:32 +0000
committerPavel Labath <labath@google.com>2015-05-27 12:40:32 +0000
commit4446487d71c52a925c04acfcae44dec8a8d62e00 (patch)
treed900259ace88e004e696e947105c1826d9eaec55 /lldb/source/Host/common/Editline.cpp
parentbed77de0021fc670709eac1a8246febce110834d (diff)
downloadbcm5719-llvm-4446487d71c52a925c04acfcae44dec8a8d62e00.tar.gz
bcm5719-llvm-4446487d71c52a925c04acfcae44dec8a8d62e00.zip
Improve LLDB prompt handling
Summary: There is an issue in lldb where the command prompt can appear at the wrong time. The partial fix we have in for this is not working all the time and is introducing unnecessary delays. This change does: - Change Process:SyncIOHandler to use integer start id's for synchronization to avoid it being confused by quick start-stop cycles. I picked this up from a suggested patch by Greg to lldb-dev. - coordinates printing of asynchronous text with the iohandlers. This is also based on a (different) Greg's patch, but I have added stronger synchronization to it to avoid races. Together, these changes solve the prompt problem for me on linux (both with and without libedit). I think they should behave similarly on Mac and FreeBSD and I think they will not make matters worse for windows. Test Plan: Prompt comes out alright. All tests still pass on linux. Reviewers: clayborg, emaste, zturner Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D9823 llvm-svn: 238313
Diffstat (limited to 'lldb/source/Host/common/Editline.cpp')
-rw-r--r--lldb/source/Host/common/Editline.cpp105
1 files changed, 67 insertions, 38 deletions
diff --git a/lldb/source/Host/common/Editline.cpp b/lldb/source/Host/common/Editline.cpp
index 3d0d4d3dfb8..0264c4b3309 100644
--- a/lldb/source/Host/common/Editline.cpp
+++ b/lldb/source/Host/common/Editline.cpp
@@ -20,6 +20,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Mutex.h"
+#include "lldb/Utility/LLDBAssert.h"
using namespace lldb_private;
using namespace lldb_private::line_editor;
@@ -581,9 +582,22 @@ Editline::GetCharacter (EditLineCharType * c)
{
lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess;
char ch = 0;
- m_editor_getting_char = true;
+
+ // This mutex is locked by our caller (GetLine). Unlock it while we read a character
+ // (blocking operation), so we do not hold the mutex indefinitely. This gives a chance
+ // for someone to interrupt us. After Read returns, immediately lock the mutex again and
+ // check if we were interrupted.
+ m_output_mutex.Unlock();
int read_count = m_input_connection.Read(&ch, 1, UINT32_MAX, status, NULL);
- m_editor_getting_char = false;
+ m_output_mutex.Lock();
+ if (m_editor_status == EditorStatus::Interrupted)
+ {
+ while (read_count > 0 && status == lldb::eConnectionStatusSuccess)
+ read_count = m_input_connection.Read(&ch, 1, UINT32_MAX, status, NULL);
+ lldbassert(status == lldb::eConnectionStatusInterrupted);
+ return 0;
+ }
+
if (read_count)
{
#if LLDB_EDITLINE_USE_WCHAR
@@ -602,14 +616,12 @@ Editline::GetCharacter (EditLineCharType * c)
{
switch (status)
{
- case lldb::eConnectionStatusInterrupted:
- m_editor_status = EditorStatus::Interrupted;
- printf ("^C\n");
- return 0;
-
case lldb::eConnectionStatusSuccess: // Success
break;
+ case lldb::eConnectionStatusInterrupted:
+ lldbassert(0 && "Interrupts should have been handled above.");
+
case lldb::eConnectionStatusError: // Check GetError() for details
case lldb::eConnectionStatusTimedOut: // Request timed out
case lldb::eConnectionStatusEndOfFile: // End-of-file encountered
@@ -1252,41 +1264,31 @@ Editline::GetCurrentLine()
return m_current_line_index;
}
-void
-Editline::Hide()
-{
- // Make sure we're at a stable location waiting for input
- while (m_editor_status == EditorStatus::Editing && !m_editor_getting_char)
- {
- usleep(100000);
- }
-
- // Clear the existing input
- if (m_editor_status == EditorStatus::Editing)
- {
- MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
- fprintf(m_output_file, ANSI_CLEAR_BELOW);
- }
-}
-
-void
-Editline::Refresh()
+bool
+Editline::Interrupt()
{
- if (m_editor_status == EditorStatus::Editing)
- {
- DisplayInput();
- MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
+ bool result = true;
+ Mutex::Locker locker(m_output_mutex);
+ if (m_editor_status == EditorStatus::Editing) {
+ fprintf(m_output_file, "^C\n");
+ result = m_input_connection.InterruptRead();
}
+ m_editor_status = EditorStatus::Interrupted;
+ return result;
}
bool
-Editline::Interrupt()
+Editline::Cancel()
{
- if (m_editor_status == EditorStatus::Editing)
- {
- return m_input_connection.InterruptRead();
+ bool result = true;
+ Mutex::Locker locker(m_output_mutex);
+ if (m_editor_status == EditorStatus::Editing) {
+ MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
+ fprintf(m_output_file, ANSI_CLEAR_BELOW);
+ result = m_input_connection.InterruptRead();
}
- return false; // Interrupt not handled as we weren't getting a line or lines
+ m_editor_status = EditorStatus::Interrupted;
+ return result;
}
void
@@ -1321,14 +1323,23 @@ Editline::GetLine (std::string &line, bool &interrupted)
m_input_lines = std::vector<EditLineStringType>();
m_input_lines.insert (m_input_lines.begin(), EditLineConstString(""));
+ Mutex::Locker locker(m_output_mutex);
+
+ lldbassert(m_editor_status != EditorStatus::Editing);
+ if (m_editor_status == EditorStatus::Interrupted)
+ {
+ m_editor_status = EditorStatus::Complete;
+ interrupted = true;
+ return true;
+ }
+
SetCurrentLine (0);
m_in_history = false;
m_editor_status = EditorStatus::Editing;
- m_editor_getting_char = false;
m_revert_cursor_index = -1;
#ifdef USE_SETUPTERM_WORKAROUND
- setupterm((char *)0, fileno(m_output_file), (int *)0);
+ setupterm((char *)0, fileno(m_output_file), (int *)0);
#endif
int count;
@@ -1366,12 +1377,12 @@ Editline::GetLines (int first_line_number, StringList &lines, bool &interrupted)
m_input_lines = std::vector<EditLineStringType>();
m_input_lines.insert (m_input_lines.begin(), EditLineConstString(""));
+ Mutex::Locker locker(m_output_mutex);
// Begin the line editing loop
DisplayInput();
SetCurrentLine (0);
MoveCursor (CursorLocation::BlockEnd, CursorLocation::BlockStart);
m_editor_status = EditorStatus::Editing;
- m_editor_getting_char = false;
m_in_history = false;
m_revert_cursor_index = -1;
@@ -1396,3 +1407,21 @@ Editline::GetLines (int first_line_number, StringList &lines, bool &interrupted)
}
return m_editor_status != EditorStatus::EndOfInput;
}
+
+void
+Editline::PrintAsync (Stream *stream, const char *s, size_t len)
+{
+ Mutex::Locker locker(m_output_mutex);
+ if (m_editor_status == EditorStatus::Editing)
+ {
+ MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
+ fprintf(m_output_file, ANSI_CLEAR_BELOW);
+ }
+ stream->Write (s, len);
+ stream->Flush();
+ if (m_editor_status == EditorStatus::Editing)
+ {
+ DisplayInput();
+ MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
+ }
+}
OpenPOWER on IntegriCloud