diff --git a/lldb/tools/lldb-mi/MICmnStreamStdin.cpp b/lldb/tools/lldb-mi/MICmnStreamStdin.cpp index 8dccf16fca2a..2d54921d323c 100644 --- a/lldb/tools/lldb-mi/MICmnStreamStdin.cpp +++ b/lldb/tools/lldb-mi/MICmnStreamStdin.cpp @@ -435,3 +435,15 @@ CMICmnStreamStdin::SetOSStdinHandler(IOSStdinHandler &vrHandler) return MIstatus::success; } +//++ ------------------------------------------------------------------------------------ +// Details: Do some actions before exiting. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +void +CMICmnStreamStdin::OnExitHandler(void) +{ + m_pStdinReadHandler->InterruptReadLine(); +} diff --git a/lldb/tools/lldb-mi/MICmnStreamStdin.h b/lldb/tools/lldb-mi/MICmnStreamStdin.h index 7b31a644103a..a6779d531669 100644 --- a/lldb/tools/lldb-mi/MICmnStreamStdin.h +++ b/lldb/tools/lldb-mi/MICmnStreamStdin.h @@ -66,6 +66,7 @@ class CMICmnStreamStdin : public CMICmnBase, public CMIUtilThreadActiveObjBase, public: virtual bool InputAvailable(bool &vwbAvail) = 0; virtual const MIchar *ReadLine(CMIUtilString &vwErrMsg) = 0; + virtual void InterruptReadLine(void){}; /* dtor */ virtual ~IOSStdinHandler(void){}; }; @@ -82,6 +83,7 @@ class CMICmnStreamStdin : public CMICmnBase, public CMIUtilThreadActiveObjBase, void SetCtrlCHit(void); bool SetVisitor(IStreamStdin &vrVisitor); bool SetOSStdinHandler(IOSStdinHandler &vrHandler); + void OnExitHandler(void); // Overridden: public: diff --git a/lldb/tools/lldb-mi/MICmnStreamStdinLinux.cpp b/lldb/tools/lldb-mi/MICmnStreamStdinLinux.cpp index ef9030b21826..07e652d84c19 100644 --- a/lldb/tools/lldb-mi/MICmnStreamStdinLinux.cpp +++ b/lldb/tools/lldb-mi/MICmnStreamStdinLinux.cpp @@ -20,12 +20,10 @@ //-- // Third Party Headers: -#if !defined(_MSC_VER) +#if defined(__APPLE__) #include -#include -#include -#include -#endif // !defined( _MSC_VER ) +#include // For STDIN_FILENO +#endif // defined( __APPLE__ ) #include // For std::strerror() // In-house headers: @@ -155,20 +153,27 @@ CMICmnStreamStdinLinux::Shutdown(void) bool CMICmnStreamStdinLinux::InputAvailable(bool &vwbAvail) { -#if !defined(_WIN32) +#if defined(__APPLE__) // The code below is needed on OSX where lldb-mi hangs when doing -exec-run. // The hang seems to come from calling fgets and fileno from different thread. // Although this problem was not observed on Linux. - // A solution based on 'select' was also proposed but it seems to slow things down - // a lot. - int nBytesWaiting; - if (::ioctl(STDIN_FILENO, FIONREAD, &nBytesWaiting) == -1) + // A solution based on 'ioctl' was initially committed but it seems to make + // lldb-mi takes much more processor time. The solution based on 'select' works + // well but it seems to slow the execution of lldb-mi tests a lot on Linux. + // As a result, this code is #defined to run only on OSX. + fd_set setOfStdin; + FD_ZERO(&setOfStdin); + FD_SET(STDIN_FILENO, &setOfStdin); + + // Wait while input would be available + if (::select(STDIN_FILENO + 1, &setOfStdin, nullptr, nullptr, nullptr) == -1) { vwbAvail = false; - return MIstatus::failure;; + return MIstatus::failure; } - vwbAvail = (nBytesWaiting > 0); -#endif // !defined( _WIN32 ) + +#endif // defined( __APPLE__ ) + vwbAvail = true; return MIstatus::success; } @@ -206,3 +211,15 @@ CMICmnStreamStdinLinux::ReadLine(CMIUtilString &vwErrMsg) return pText; } +//++ ------------------------------------------------------------------------------------ +// Details: Interrupt current and prevent new ReadLine operations. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +void +CMICmnStreamStdinLinux::InterruptReadLine(void) +{ + fclose(stdin); +} diff --git a/lldb/tools/lldb-mi/MICmnStreamStdinLinux.h b/lldb/tools/lldb-mi/MICmnStreamStdinLinux.h index 34717225eba0..edac94034f57 100644 --- a/lldb/tools/lldb-mi/MICmnStreamStdinLinux.h +++ b/lldb/tools/lldb-mi/MICmnStreamStdinLinux.h @@ -51,6 +51,7 @@ class CMICmnStreamStdinLinux : public CMICmnBase, public CMICmnStreamStdin::IOSS // From CMICmnStreamStdin::IOSpecificReadStreamStdin virtual bool InputAvailable(bool &vwbAvail); virtual const MIchar *ReadLine(CMIUtilString &vwErrMsg); + virtual void InterruptReadLine(void); // Methods: private: diff --git a/lldb/tools/lldb-mi/MIDriver.cpp b/lldb/tools/lldb-mi/MIDriver.cpp index a16c62f773ac..accde1c7cde7 100644 --- a/lldb/tools/lldb-mi/MIDriver.cpp +++ b/lldb/tools/lldb-mi/MIDriver.cpp @@ -1075,6 +1075,7 @@ CMIDriver::SetExitApplicationFlag(const bool vbForceExit) { CMIUtilThreadLock lock(m_threadMutex); m_bExitApp = true; + m_rStdin.OnExitHandler(); return; } @@ -1089,6 +1090,7 @@ CMIDriver::SetExitApplicationFlag(const bool vbForceExit) } m_bExitApp = true; + m_rStdin.OnExitHandler(); } //++ ------------------------------------------------------------------------------------