JDevlieghere created this revision.
JDevlieghere added a reviewer: labath.
Herald added a project: All.
JDevlieghere requested review of this revision.

Alternative to D121500 <https://reviews.llvm.org/D121500> that does the locking 
at the IOHandler level.


https://reviews.llvm.org/D121537

Files:
  lldb/include/lldb/Core/IOHandler.h
  lldb/include/lldb/Interpreter/CommandInterpreter.h
  lldb/source/Core/IOHandler.cpp
  lldb/source/Interpreter/CommandInterpreter.cpp

Index: lldb/source/Interpreter/CommandInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/CommandInterpreter.cpp
+++ lldb/source/Interpreter/CommandInterpreter.cpp
@@ -2975,8 +2975,12 @@
   return was_interrupted;
 }
 
-void CommandInterpreter::PrintCommandOutput(Stream &stream,
-                                            llvm::StringRef str) {
+void CommandInterpreter::PrintCommandOutput(IOHandler &io_handler,
+                                            llvm::StringRef str,
+                                            bool is_stdout) {
+
+  lldb::StreamFileSP stream = is_stdout ? io_handler.GetOutputStreamFileSP()
+                                        : io_handler.GetErrorStreamFileSP();
   // Split the output into lines and poll for interrupt requests
   const char *data = str.data();
   size_t size = str.size();
@@ -2989,15 +2993,19 @@
         break;
       }
     }
-    chunk_size = stream.Write(data, chunk_size);
+    {
+      std::lock_guard<std::mutex> guard(io_handler.GetOutputMutex());
+      chunk_size = stream->Write(data, chunk_size);
+    }
     lldbassert(size >= chunk_size);
     data += chunk_size;
     size -= chunk_size;
   }
-  if (size > 0) {
-    stream.Printf("\n... Interrupted.\n");
-  }
-  stream.Flush();
+
+  std::lock_guard<std::mutex> guard(io_handler.GetOutputMutex());
+  if (size > 0)
+    stream->Printf("\n... Interrupted.\n");
+  stream->Flush();
 }
 
 bool CommandInterpreter::EchoCommandNonInteractive(
@@ -3033,9 +3041,11 @@
     // When using a non-interactive file handle (like when sourcing commands
     // 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()))
+    if (EchoCommandNonInteractive(line, io_handler.GetFlags())) {
+      std::lock_guard<std::mutex> guard(io_handler.GetOutputMutex());
       io_handler.GetOutputStreamFileSP()->Printf(
           "%s%s\n", io_handler.GetPrompt(), line.c_str());
+    }
   }
 
   StartHandlingCommand();
@@ -3057,13 +3067,13 @@
 
     if (!result.GetImmediateOutputStream()) {
       llvm::StringRef output = result.GetOutputData();
-      PrintCommandOutput(*io_handler.GetOutputStreamFileSP(), output);
+      PrintCommandOutput(io_handler, output, true);
     }
 
     // Now emit the command error text from the command we just executed
     if (!result.GetImmediateErrorStream()) {
       llvm::StringRef error = result.GetErrorData();
-      PrintCommandOutput(*io_handler.GetErrorStreamFileSP(), error);
+      PrintCommandOutput(io_handler, error, false);
     }
   }
 
Index: lldb/source/Core/IOHandler.cpp
===================================================================
--- lldb/source/Core/IOHandler.cpp
+++ lldb/source/Core/IOHandler.cpp
@@ -123,6 +123,7 @@
 void IOHandler::WaitForPop() { m_popped.WaitForValueEqualTo(true); }
 
 void IOHandler::PrintAsync(const char *s, size_t len, bool is_stdout) {
+  std::lock_guard<std::mutex> guard(m_output_mutex);
   lldb::StreamFileSP stream = is_stdout ? m_output_sp : m_error_sp;
   stream->Write(s, len);
   stream->Flush();
@@ -619,6 +620,7 @@
 void IOHandlerEditline::PrintAsync(const char *s, size_t len, bool is_stdout) {
 #if LLDB_ENABLE_LIBEDIT
   if (m_editline_up) {
+    std::lock_guard<std::mutex> guard(m_output_mutex);
     lldb::StreamFileSP stream = is_stdout ? m_output_sp : m_error_sp;
     m_editline_up->PrintAsync(stream.get(), s, len);
   } else
Index: lldb/include/lldb/Interpreter/CommandInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -655,7 +655,8 @@
                               const CommandObject::CommandMap &command_map);
 
   // An interruptible wrapper around the stream output
-  void PrintCommandOutput(Stream &stream, llvm::StringRef str);
+  void PrintCommandOutput(IOHandler &io_handler, llvm::StringRef str,
+                          bool is_stdout0);
 
   bool EchoCommandNonInteractive(llvm::StringRef line,
                                  const Flags &io_handler_flags) const;
Index: lldb/include/lldb/Core/IOHandler.h
===================================================================
--- lldb/include/lldb/Core/IOHandler.h
+++ lldb/include/lldb/Core/IOHandler.h
@@ -165,11 +165,14 @@
 
   virtual void PrintAsync(const char *s, size_t len, bool is_stdout);
 
+  std::mutex &GetOutputMutex() { return m_output_mutex; }
+
 protected:
   Debugger &m_debugger;
   lldb::FileSP m_input_sp;
   lldb::StreamFileSP m_output_sp;
   lldb::StreamFileSP m_error_sp;
+  std::mutex m_output_mutex;
   repro::DataRecorder *m_data_recorder;
   Predicate<bool> m_popped;
   Flags m_flags;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to