================ @@ -83,24 +86,68 @@ class JSONTransport { return WriteImpl(message); } - /// Reads the next message from the input stream. + /// Registers the transport with the MainLoop. template <typename T> - llvm::Expected<T> Read(const std::chrono::microseconds &timeout) { - llvm::Expected<std::string> message = ReadImpl(timeout); - if (!message) - return message.takeError(); - return llvm::json::parse<T>(/*JSON=*/*message); + llvm::Expected<ReadHandleUP> RegisterReadObject(MainLoopBase &loop, + Callback<T> read_cb) { + Status error; + ReadHandleUP handle = loop.RegisterReadObject( + m_input, + [read_cb, this](MainLoopBase &loop) { + char buf[kReadBufferSize]; + size_t num_bytes = sizeof(buf); + if (llvm::Error error = m_input->Read(buf, num_bytes).takeError()) { + read_cb(loop, std::move(error)); + return; + } + if (num_bytes) + m_buffer.append(std::string(buf, num_bytes)); + + // If the buffer has contents, try parsing any pending messages. + if (!m_buffer.empty()) { + llvm::Expected<std::vector<std::string>> messages = Parse(); + if (llvm::Error error = messages.takeError()) { + read_cb(loop, std::move(error)); + return; + } + + for (const auto &message : *messages) + if constexpr (std::is_same<T, std::string>::value) + read_cb(loop, message); + else + read_cb(loop, llvm::json::parse<T>(message)); + } + + // On EOF, notify the callback after the remaining messages were + // handled. + if (num_bytes == 0) { + if (m_buffer.empty()) + read_cb(loop, llvm::make_error<TransportEOFError>()); + else + read_cb(loop, llvm::make_error<TransportUnhandledContentsError>( + std::string(m_buffer))); + } + }, + error); + if (error.Fail()) + return error.takeError(); + return handle; } protected: + template <typename... Ts> inline auto Logv(const char *Fmt, Ts &&...Vals) { + Log(llvm::formatv(Fmt, std::forward<Ts>(Vals)...).str()); + } virtual void Log(llvm::StringRef message); virtual llvm::Error WriteImpl(const std::string &message) = 0; - virtual llvm::Expected<std::string> - ReadImpl(const std::chrono::microseconds &timeout) = 0; + virtual llvm::Expected<std::vector<std::string>> Parse() = 0; lldb::IOObjectSP m_input; lldb::IOObjectSP m_output; + llvm::SmallString<128> m_buffer; ---------------- JDevlieghere wrote:
Shouldn't this be at least `kReadBufferSize`? https://github.com/llvm/llvm-project/pull/152367 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits