[Lldb-commits] [lldb] r287920 - Introduce chrono to the Communication class

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Fri Nov 25 03:58:45 PST 2016


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)))));
+}




More information about the lldb-commits mailing list