diff options
| author | Pavel Labath <labath@google.com> | 2015-05-27 12:40:32 +0000 |
|---|---|---|
| committer | Pavel Labath <labath@google.com> | 2015-05-27 12:40:32 +0000 |
| commit | 4446487d71c52a925c04acfcae44dec8a8d62e00 (patch) | |
| tree | d900259ace88e004e696e947105c1826d9eaec55 /lldb/source/Host/common/Editline.cpp | |
| parent | bed77de0021fc670709eac1a8246febce110834d (diff) | |
| download | bcm5719-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.cpp | 105 |
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); + } +} |

