llvm-capstone/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
Pavel Labath 1eff73c324 Introduce chrono to more gdb-remote functions
Summary:
This replaces the usage of raw integers with duration classes in the gdb-remote
packet management functions. The values are still converted back to integers once
they go into the generic Communication class -- that I am leaving to a separate
change.

The changes are mostly straight-forward (*), the only tricky part was
representation of infinite timeouts.

Currently, we use UINT32_MAX to denote infinite timeout. This is not well suited
for duration classes, as they tend to do arithmetic on the values, and the
identity of the MAX value can easily get lost (e.g.
microseconds(seconds(UINT32_MAX)).count() != UINT32_MAX). We cannot use zero to
represent infinity (as Listener classes do) because we already use it to do
non-blocking polling reads. For this reason, I chose to have an explicit value
for infinity.

The way I achieved that is via llvm::Optional, and I think it reads quite
natural. Passing llvm::None as "timeout" means "no timeout", while passing zero
means "poll". The only tricky part is this breaks implicit conversions (seconds
are implicitly convertible to microseconds, but Optional<seconds> cannot be
easily converted into Optional<microseconds>). For this reason I added a special
class Timeout, inheriting from Optional, and enabling the necessary conversions
one would normally expect.

(*) The other tricky part was GDBRemoteCommunication::PopPacketFromQueue, which
was needlessly complicated. I've simplified it, but that one is only used in
non-stop mode, and so is untested.

Reviewers: clayborg, zturner, jingham

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D26971

llvm-svn: 287864
2016-11-24 10:54:49 +00:00

77 lines
2.3 KiB
C++

//===-- GDBRemoteCommunicationServer.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_GDBRemoteCommunicationServer_h_
#define liblldb_GDBRemoteCommunicationServer_h_
// C Includes
// C++ Includes
#include <functional>
#include <map>
// Other libraries and framework includes
// Project includes
#include "GDBRemoteCommunication.h"
#include "lldb/lldb-private-forward.h"
class StringExtractorGDBRemote;
namespace lldb_private {
namespace process_gdb_remote {
class ProcessGDBRemote;
class GDBRemoteCommunicationServer : public GDBRemoteCommunication {
public:
using PortMap = std::map<uint16_t, lldb::pid_t>;
using PacketHandler =
std::function<PacketResult(StringExtractorGDBRemote &packet, Error &error,
bool &interrupt, bool &quit)>;
GDBRemoteCommunicationServer(const char *comm_name,
const char *listener_name);
~GDBRemoteCommunicationServer() override;
void
RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
PacketHandler handler);
PacketResult GetPacketAndSendResponse(Timeout<std::micro> timeout,
Error &error, bool &interrupt,
bool &quit);
// After connecting, do a little handshake with the client to make sure
// we are at least communicating
bool HandshakeWithClient();
protected:
std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler>
m_packet_handlers;
bool m_exit_now; // use in asynchronous handling to indicate process should
// exit.
PacketResult SendUnimplementedResponse(const char *packet);
PacketResult SendErrorResponse(uint8_t error);
PacketResult SendIllFormedResponse(const StringExtractorGDBRemote &packet,
const char *error_message);
PacketResult SendOKResponse();
private:
DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServer);
};
} // namespace process_gdb_remote
} // namespace lldb_private
#endif // liblldb_GDBRemoteCommunicationServer_h_