Author: labath Date: Fri Nov 25 05:58:44 2016 New Revision: 287920 URL: http://llvm.org/viewvc/llvm-project?rev=287920&view=rev Log: Introduce chrono to the Communication class
This replaces the raw integer timeout parameters in the class with their chrono-based equivalents. To achieve this, I have moved the Timeout class to a more generic place and added a quick unit test for it. Added: lldb/trunk/include/lldb/Utility/Timeout.h lldb/trunk/unittests/Utility/TimeoutTest.cpp Modified: lldb/trunk/include/lldb/Core/Communication.h lldb/trunk/source/API/SBCommunication.cpp lldb/trunk/source/Core/Communication.cpp lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp lldb/trunk/unittests/Utility/CMakeLists.txt Modified: lldb/trunk/include/lldb/Core/Communication.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Communication.h?rev=287920&r1=287919&r2=287920&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Communication.h (original) +++ lldb/trunk/include/lldb/Core/Communication.h Fri Nov 25 05:58:44 2016 @@ -21,7 +21,7 @@ #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Error.h" #include "lldb/Host/HostThread.h" -#include "lldb/lldb-private.h" +#include "lldb/Utility/Timeout.h" #include "lldb/lldb-private.h" namespace lldb_private { @@ -196,15 +196,15 @@ public: /// The number of bytes to attempt to read, and also the max /// number of bytes that can be placed into \a dst. /// - /// @param[in] timeout_usec - /// A timeout value in micro-seconds. + /// @param[in] timeout + /// A timeout value or llvm::None for no timeout. /// /// @return /// The number of bytes actually read. /// /// @see size_t Connection::Read (void *, size_t); //------------------------------------------------------------------ - size_t Read(void *dst, size_t dst_len, uint32_t timeout_usec, + size_t Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout, lldb::ConnectionStatus &status, Error *error_ptr); //------------------------------------------------------------------ @@ -347,7 +347,8 @@ protected: void *m_callback_baton; bool m_close_on_eof; - size_t ReadFromConnection(void *dst, size_t dst_len, uint32_t timeout_usec, + size_t ReadFromConnection(void *dst, size_t dst_len, + const Timeout<std::micro> &timeout, lldb::ConnectionStatus &status, Error *error_ptr); //------------------------------------------------------------------ Added: lldb/trunk/include/lldb/Utility/Timeout.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/Timeout.h?rev=287920&view=auto ============================================================================== --- lldb/trunk/include/lldb/Utility/Timeout.h (added) +++ lldb/trunk/include/lldb/Utility/Timeout.h Fri Nov 25 05:58:44 2016 @@ -0,0 +1,56 @@ +//===-- Timeout.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Timeout_h_ +#define liblldb_Timeout_h_ + +#include <llvm/ADT/Optional.h> + +#include <chrono> + +namespace lldb_private { + +// A general purpose class for representing timeouts for various APIs. It's +// basically an llvm::Optional<std::chrono::duration<int64_t, Ratio>>, but we +// customize it a bit to enable the standard chrono implicit conversions (e.g. +// from Timeout<std::milli> to Timeout<std::micro>. +// +// The intended meaning of the values is: +// - llvm::None - no timeout, the call should wait forever +// - 0 - poll, only complete the call if it will not block +// - >0 - wait for a given number of units for the result +template <typename Ratio> +class Timeout : public llvm::Optional<std::chrono::duration<int64_t, Ratio>> { +private: + template <typename Ratio2> using Dur = std::chrono::duration<int64_t, Ratio2>; + template <typename Rep2, typename Ratio2> + using EnableIf = std::enable_if< + std::is_convertible<std::chrono::duration<Rep2, Ratio2>, + std::chrono::duration<int64_t, Ratio>>::value>; + + using Base = llvm::Optional<Dur<Ratio>>; + +public: + Timeout(llvm::NoneType none) : Base(none) {} + Timeout(const Timeout &other) = default; + + template <typename Ratio2, + typename = typename EnableIf<int64_t, Ratio2>::type> + Timeout(const Timeout<Ratio2> &other) + : Base(other ? Base(Dur<Ratio>(*other)) : llvm::None) {} + + template <typename Rep2, typename Ratio2, + typename = typename EnableIf<Rep2, Ratio2>::type> + Timeout(const std::chrono::duration<Rep2, Ratio2> &other) + : Base(Dur<Ratio>(other)) {} +}; + +} // namespace lldb_private + +#endif // liblldb_Timeout_h_ Modified: lldb/trunk/source/API/SBCommunication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommunication.cpp?rev=287920&r1=287919&r2=287920&view=diff ============================================================================== --- lldb/trunk/source/API/SBCommunication.cpp (original) +++ lldb/trunk/source/API/SBCommunication.cpp Fri Nov 25 05:58:44 2016 @@ -119,8 +119,11 @@ size_t SBCommunication::Read(void *dst, static_cast<void *>(m_opaque), static_cast<void *>(dst), static_cast<uint64_t>(dst_len), timeout_usec); size_t bytes_read = 0; + Timeout<std::micro> timeout = timeout_usec == UINT32_MAX + ? Timeout<std::micro>(llvm::None) + : std::chrono::microseconds(timeout_usec); if (m_opaque) - bytes_read = m_opaque->Read(dst, dst_len, timeout_usec, status, NULL); + bytes_read = m_opaque->Read(dst, dst_len, timeout, status, NULL); else status = eConnectionStatusNoConnection; Modified: lldb/trunk/source/Core/Communication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Communication.cpp?rev=287920&r1=287919&r2=287920&view=diff ============================================================================== --- lldb/trunk/source/Core/Communication.cpp (original) +++ lldb/trunk/source/Core/Communication.cpp Fri Nov 25 05:58:44 2016 @@ -112,18 +112,20 @@ bool Communication::HasConnection() cons return m_connection_sp.get() != nullptr; } -size_t Communication::Read(void *dst, size_t dst_len, uint32_t timeout_usec, +size_t Communication::Read(void *dst, size_t dst_len, + const Timeout<std::micro> &timeout, ConnectionStatus &status, Error *error_ptr) { lldb_private::LogIfAnyCategoriesSet( LIBLLDB_LOG_COMMUNICATION, "%p Communication::Read (dst = %p, dst_len = %" PRIu64 ", timeout = %u usec) connection = %p", - this, dst, (uint64_t)dst_len, timeout_usec, m_connection_sp.get()); + this, dst, (uint64_t)dst_len, timeout ? timeout->count() : -1, + m_connection_sp.get()); if (m_read_thread_enabled) { // We have a dedicated read thread that is getting data for us size_t cached_bytes = GetCachedBytes(dst, dst_len); - if (cached_bytes > 0 || timeout_usec == 0) { + if (cached_bytes > 0 || (timeout && timeout->count() == 0)) { status = eConnectionStatusSuccess; return cached_bytes; } @@ -139,10 +141,9 @@ size_t Communication::Read(void *dst, si listener_sp->StartListeningForEvents( this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit); EventSP event_sp; - std::chrono::microseconds timeout = std::chrono::microseconds(0); - if (timeout_usec != UINT32_MAX) - timeout = std::chrono::microseconds(timeout_usec); - while (listener_sp->WaitForEvent(timeout, event_sp)) { + std::chrono::microseconds listener_timeout = + timeout ? *timeout : std::chrono::microseconds(0); + while (listener_sp->WaitForEvent(listener_timeout, event_sp)) { const uint32_t event_type = event_sp->GetType(); if (event_type & eBroadcastBitReadThreadGotBytes) { return GetCachedBytes(dst, dst_len); @@ -159,15 +160,7 @@ size_t Communication::Read(void *dst, si // We aren't using a read thread, just read the data synchronously in this // thread. - lldb::ConnectionSP connection_sp(m_connection_sp); - if (connection_sp) { - return connection_sp->Read(dst, dst_len, timeout_usec, status, error_ptr); - } - - if (error_ptr) - error_ptr->SetErrorString("Invalid connection."); - status = eConnectionStatusNoConnection; - return 0; + return ReadFromConnection(dst, dst_len, timeout, status, error_ptr); } size_t Communication::Write(const void *src, size_t src_len, @@ -279,14 +272,20 @@ void Communication::AppendBytesToCache(c } size_t Communication::ReadFromConnection(void *dst, size_t dst_len, - uint32_t timeout_usec, + const Timeout<std::micro> &timeout, ConnectionStatus &status, Error *error_ptr) { lldb::ConnectionSP connection_sp(m_connection_sp); - return ( - connection_sp - ? connection_sp->Read(dst, dst_len, timeout_usec, status, error_ptr) - : 0); + if (connection_sp) { + return connection_sp->Read(dst, dst_len, + timeout ? timeout->count() : UINT32_MAX, status, + error_ptr); + } + + if (error_ptr) + error_ptr->SetErrorString("Invalid connection."); + status = eConnectionStatusNoConnection; + return 0; } bool Communication::ReadThreadIsRunning() { return m_read_thread_enabled; } @@ -305,9 +304,8 @@ lldb::thread_result_t Communication::Rea ConnectionStatus status = eConnectionStatusSuccess; bool done = false; while (!done && comm->m_read_thread_enabled) { - const int timeout_us = 5000000; size_t bytes_read = comm->ReadFromConnection( - buf, sizeof(buf), timeout_us, status, &error); + buf, sizeof(buf), std::chrono::seconds(5), status, &error); if (bytes_read > 0) comm->AppendBytesToCache(buf, bytes_read, true, status); else if ((bytes_read == 0) && status == eConnectionStatusEndOfFile) { Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=287920&r1=287919&r2=287920&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Fri Nov 25 05:58:44 2016 @@ -332,9 +332,7 @@ GDBRemoteCommunication::WaitForPacketNoL bool disconnected = false; while (IsConnected() && !timed_out) { lldb::ConnectionStatus status = eConnectionStatusNoConnection; - size_t bytes_read = - Read(buffer, sizeof(buffer), timeout ? timeout->count() : UINT32_MAX, - status, &error); + size_t bytes_read = Read(buffer, sizeof(buffer), timeout, status, &error); if (log) log->Printf("%s: Read (buffer, (sizeof(buffer), timeout = %ld us, " Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=287920&r1=287919&r2=287920&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Fri Nov 25 05:58:44 2016 @@ -53,32 +53,6 @@ enum class CompressionType { class ProcessGDBRemote; -template <typename Ratio> -class Timeout : public llvm::Optional<std::chrono::duration<int64_t, Ratio>> { -private: - template <typename Ratio2> using Dur = std::chrono::duration<int64_t, Ratio2>; - template <typename Rep2, typename Ratio2> - using EnableIf = std::enable_if< - std::is_convertible<std::chrono::duration<Rep2, Ratio2>, - std::chrono::duration<int64_t, Ratio>>::value>; - - using Base = llvm::Optional<Dur<Ratio>>; - -public: - Timeout(llvm::NoneType none) : Base(none) {} - Timeout(const Timeout &other) = default; - - template <typename Ratio2, - typename = typename EnableIf<int64_t, Ratio2>::type> - Timeout(const Timeout<Ratio2> &other) - : Base(other ? Base(Dur<Ratio>(*other)) : llvm::None) {} - - template <typename Rep2, typename Ratio2, - typename = typename EnableIf<Rep2, Ratio2>::type> - Timeout(const std::chrono::duration<Rep2, Ratio2> &other) - : Base(Dur<Ratio>(other)) {} -}; - class GDBRemoteCommunication : public Communication { public: enum { Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp?rev=287920&r1=287919&r2=287920&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp Fri Nov 25 05:58:44 2016 @@ -1021,8 +1021,8 @@ void GDBRemoteCommunicationServerLLGS::S ConnectionStatus status; Error error; while (true) { - size_t bytes_read = - m_stdio_communication.Read(buffer, sizeof buffer, 0, status, &error); + size_t bytes_read = m_stdio_communication.Read( + buffer, sizeof buffer, std::chrono::microseconds(0), status, &error); switch (status) { case eConnectionStatusSuccess: SendONotification(buffer, bytes_read); Modified: lldb/trunk/unittests/Utility/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/CMakeLists.txt?rev=287920&r1=287919&r2=287920&view=diff ============================================================================== --- lldb/trunk/unittests/Utility/CMakeLists.txt (original) +++ lldb/trunk/unittests/Utility/CMakeLists.txt Fri Nov 25 05:58:44 2016 @@ -2,6 +2,7 @@ add_lldb_unittest(UtilityTests ModuleCacheTest.cpp StringExtractorTest.cpp TaskPoolTest.cpp + TimeoutTest.cpp UriParserTest.cpp ) Added: lldb/trunk/unittests/Utility/TimeoutTest.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Utility/TimeoutTest.cpp?rev=287920&view=auto ============================================================================== --- lldb/trunk/unittests/Utility/TimeoutTest.cpp (added) +++ lldb/trunk/unittests/Utility/TimeoutTest.cpp Fri Nov 25 05:58:44 2016 @@ -0,0 +1,22 @@ +//===-- TimeoutTest.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/Timeout.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace std::chrono; + +TEST(TimeoutTest, Construction) { + ASSERT_FALSE(Timeout<std::micro>(llvm::None)); + ASSERT_TRUE(bool(Timeout<std::micro>(seconds(0)))); + ASSERT_EQ(seconds(0), *Timeout<std::micro>(seconds(0))); + ASSERT_EQ(seconds(3), *Timeout<std::micro>(seconds(3))); + ASSERT_TRUE(bool(Timeout<std::micro>(Timeout<std::milli>(seconds(0))))); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits