diff options
author | Jonas Devlieghere <jonas@devlieghere.com> | 2025-02-19 20:32:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-19 20:32:00 -0800 |
commit | 58279d1ee1b567e8ca793d6d1eb6e0f1d5e7279e (patch) | |
tree | 4e1c25b423d78f003b9a781d7753600867465b9f /lldb/source/Interpreter/CommandInterpreter.cpp | |
parent | 557628dbe6a935b1ad5e1bcfd51ac3a65e35d874 (diff) | |
download | llvm-58279d1ee1b567e8ca793d6d1eb6e0f1d5e7279e.zip llvm-58279d1ee1b567e8ca793d6d1eb6e0f1d5e7279e.tar.gz llvm-58279d1ee1b567e8ca793d6d1eb6e0f1d5e7279e.tar.bz2 |
[lldb] Synchronize the debuggers output & error streams
This patch improves the synchronization of the debugger's output and error
streams using two new abstractions: `LockableStreamFile` and
`LockedStreamFile`.
- `LockableStreamFile` is a wrapper around a `StreamFile` and a mutex. Client
cannot use the `StreamFile` without calling `Lock`, which returns a
`LockedStreamFile`.
- `LockedStreamFile` is an RAII object that locks the stream for the duration
of its existence. As long as you hold on to the returned object you are
permitted to write to the stream. The destruction of the object
automatically flush the output stream.
Diffstat (limited to 'lldb/source/Interpreter/CommandInterpreter.cpp')
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 5346d5a..c363f200 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -57,6 +57,7 @@ #include "lldb/Utility/Timer.h" #include "lldb/Host/Config.h" +#include "lldb/lldb-forward.h" #if LLDB_ENABLE_LIBEDIT #include "lldb/Host/Editline.h" #endif @@ -2843,7 +2844,7 @@ void CommandInterpreter::HandleCommandsFromFile( // Used for inheriting the right settings when "command source" might // have nested "command source" commands - lldb::StreamFileSP empty_stream_sp; + lldb::LockableStreamFileSP empty_stream_sp; m_command_source_flags.push_back(flags); IOHandlerSP io_handler_sp(new IOHandlerEditline( debugger, IOHandler::Type::CommandInterpreter, input_file_sp, @@ -3100,25 +3101,26 @@ void CommandInterpreter::PrintCommandOutput(IOHandler &io_handler, llvm::StringRef str, bool is_stdout) { - lldb::StreamFileSP stream = is_stdout ? io_handler.GetOutputStreamFileSP() - : io_handler.GetErrorStreamFileSP(); + lldb::LockableStreamFileSP stream = is_stdout + ? io_handler.GetOutputStreamFileSP() + : io_handler.GetErrorStreamFileSP(); // Split the output into lines and poll for interrupt requests bool had_output = !str.empty(); while (!str.empty()) { llvm::StringRef line; std::tie(line, str) = str.split('\n'); { - std::lock_guard<std::recursive_mutex> guard(io_handler.GetOutputMutex()); - stream->Write(line.data(), line.size()); - stream->Write("\n", 1); + LockedStreamFile stream_file = stream->Lock(); + stream_file.Write(line.data(), line.size()); + stream_file.Write("\n", 1); } } - std::lock_guard<std::recursive_mutex> guard(io_handler.GetOutputMutex()); + LockedStreamFile stream_file = stream->Lock(); if (had_output && INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping command output")) - stream->Printf("\n... Interrupted.\n"); - stream->Flush(); + stream_file.Printf("\n... Interrupted.\n"); + stream_file.Flush(); } bool CommandInterpreter::EchoCommandNonInteractive( @@ -3160,9 +3162,9 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, // from a file) we need to echo the command out so we don't just see the // command output and no command... if (EchoCommandNonInteractive(line, io_handler.GetFlags())) { - std::lock_guard<std::recursive_mutex> guard(io_handler.GetOutputMutex()); - io_handler.GetOutputStreamFileSP()->Printf( - "%s%s\n", io_handler.GetPrompt(), line.c_str()); + LockedStreamFile locked_stream = + io_handler.GetOutputStreamFileSP()->Lock(); + locked_stream.Printf("%s%s\n", io_handler.GetPrompt(), line.c_str()); } } |