base,cpu,dev: Add a level of indirection for ListenSockets.
This makes room for there to be different implementations for different types of sockets. Change-Id: I8c959e2c3400caec8242e693e11330e072bc2c5f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69162 Reviewed-by: Yu-hsin Wang <yuhsingw@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Maintainer: Gabe Black <gabe.black@gmail.com>
This commit is contained in:
@@ -392,10 +392,11 @@ std::map<Addr, HardBreakpoint *> hardBreakMap;
|
||||
|
||||
BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) :
|
||||
incomingConnectionEvent(nullptr), incomingDataEvent(nullptr),
|
||||
listener(_system->name() + ".remote_gdb", _port), fd(-1), sys(_system),
|
||||
connectEvent(*this), disconnectEvent(*this), trapEvent(this),
|
||||
singleStepEvent(*this)
|
||||
{}
|
||||
fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this),
|
||||
trapEvent(this), singleStepEvent(*this)
|
||||
{
|
||||
listener = listenSocketInetConfig(_port).build(name());
|
||||
}
|
||||
|
||||
BaseRemoteGDB::~BaseRemoteGDB()
|
||||
{
|
||||
@@ -417,25 +418,22 @@ BaseRemoteGDB::listen()
|
||||
return;
|
||||
}
|
||||
|
||||
listener.listen();
|
||||
listener->listen();
|
||||
|
||||
incomingConnectionEvent =
|
||||
new IncomingConnectionEvent(this, listener.getfd(), POLLIN);
|
||||
new IncomingConnectionEvent(this, listener->getfd(), POLLIN);
|
||||
pollQueue.schedule(incomingConnectionEvent);
|
||||
|
||||
ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n",
|
||||
curTick(), name(), listener);
|
||||
}
|
||||
|
||||
void
|
||||
BaseRemoteGDB::connect()
|
||||
{
|
||||
panic_if(!listener.islistening(),
|
||||
panic_if(!listener->islistening(),
|
||||
"Can't accept GDB connections without any threads!");
|
||||
|
||||
pollQueue.remove(incomingConnectionEvent);
|
||||
|
||||
int sfd = listener.accept();
|
||||
int sfd = listener->accept();
|
||||
|
||||
if (sfd != -1) {
|
||||
if (isAttached())
|
||||
@@ -448,9 +446,9 @@ BaseRemoteGDB::connect()
|
||||
const ListenSocket &
|
||||
BaseRemoteGDB::hostSocket() const
|
||||
{
|
||||
panic_if(!listener.islistening(),
|
||||
panic_if(!listener->islistening(),
|
||||
"Remote GDB socket is unknown until listen() has been called.");
|
||||
return listener;
|
||||
return *listener;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -513,7 +511,7 @@ BaseRemoteGDB::addThreadContext(ThreadContext *_tc)
|
||||
assert(selectThreadContext(_tc->contextId()));
|
||||
|
||||
// Now that we have a thread, we can start listening.
|
||||
if (!listener.islistening())
|
||||
if (!listener->islistening())
|
||||
listen();
|
||||
}
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ class BaseRemoteGDB
|
||||
IncomingConnectionEvent *incomingConnectionEvent;
|
||||
IncomingDataEvent *incomingDataEvent;
|
||||
|
||||
ListenSocket listener;
|
||||
ListenSocketPtr listener;
|
||||
|
||||
// The socket commands come in through.
|
||||
int fd;
|
||||
|
||||
@@ -269,4 +269,12 @@ ListenSocket::accept()
|
||||
return sfd;
|
||||
}
|
||||
|
||||
ListenSocketConfig
|
||||
listenSocketInetConfig(int port)
|
||||
{
|
||||
return ListenSocketConfig([port](const std::string &name) {
|
||||
return std::make_unique<ListenSocket>(name, port);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace gem5
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/named.hh"
|
||||
@@ -127,6 +130,33 @@ class ListenSocket : public Named
|
||||
/** @} */ // end of api_socket
|
||||
};
|
||||
|
||||
using ListenSocketPtr = std::unique_ptr<ListenSocket>;
|
||||
|
||||
class ListenSocketConfig
|
||||
{
|
||||
public:
|
||||
using Builder = std::function<ListenSocketPtr(const std::string &name)>;
|
||||
|
||||
ListenSocketConfig() {}
|
||||
ListenSocketConfig(Builder _builder) : builder(_builder) {}
|
||||
|
||||
ListenSocketPtr
|
||||
build(const std::string &name) const
|
||||
{
|
||||
assert(builder);
|
||||
return builder(name);
|
||||
}
|
||||
|
||||
operator bool() const { return (bool)builder; }
|
||||
|
||||
private:
|
||||
Builder builder;
|
||||
};
|
||||
|
||||
static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; }
|
||||
|
||||
ListenSocketConfig listenSocketInetConfig(int port);
|
||||
|
||||
inline static std::ostream &
|
||||
operator << (std::ostream &os, const ListenSocket &socket)
|
||||
{
|
||||
|
||||
@@ -117,8 +117,8 @@ VncServer::DataEvent::process(int revent)
|
||||
*/
|
||||
VncServer::VncServer(const Params &p)
|
||||
: VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number),
|
||||
listener(p.name, p.port), sendUpdate(false),
|
||||
supportsRawEnc(false), supportsResizeEnc(false)
|
||||
listener(listenSocketInetConfig(p.port).build(p.name)),
|
||||
sendUpdate(false), supportsRawEnc(false), supportsResizeEnc(false)
|
||||
{
|
||||
if (p.port)
|
||||
listen();
|
||||
@@ -164,9 +164,9 @@ VncServer::listen()
|
||||
return;
|
||||
}
|
||||
|
||||
listener.listen();
|
||||
listener->listen();
|
||||
|
||||
listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
|
||||
listenEvent = new ListenEvent(this, listener->getfd(), POLLIN);
|
||||
pollQueue.schedule(listenEvent);
|
||||
}
|
||||
|
||||
@@ -179,10 +179,10 @@ VncServer::accept()
|
||||
// thread.
|
||||
EventQueue::ScopedMigration migrate(eventQueue());
|
||||
|
||||
if (!listener.islistening())
|
||||
if (!listener->islistening())
|
||||
panic("%s: cannot accept a connection if not listening!", name());
|
||||
|
||||
int fd = listener.accept();
|
||||
int fd = listener->accept();
|
||||
if (fd < 0) {
|
||||
warn("%s: failed to accept VNC connection!", name());
|
||||
return;
|
||||
|
||||
@@ -180,7 +180,7 @@ class VncServer : public VncInput
|
||||
int number;
|
||||
int dataFd; // data stream file describer
|
||||
|
||||
ListenSocket listener;
|
||||
ListenSocketPtr listener;
|
||||
|
||||
void listen();
|
||||
void accept();
|
||||
|
||||
@@ -39,14 +39,14 @@ namespace gem5
|
||||
namespace trace {
|
||||
|
||||
NativeTrace::NativeTrace(const Params &p)
|
||||
: ExeTracer(p), native_listener(p.name, 8000)
|
||||
: ExeTracer(p), native_listener(listenSocketInetConfig(8000).build(p.name))
|
||||
{
|
||||
if (ListenSocket::allDisabled())
|
||||
fatal("All listeners are disabled!");
|
||||
|
||||
native_listener.listen();
|
||||
native_listener->listen();
|
||||
|
||||
fd = native_listener.accept();
|
||||
fd = native_listener->accept();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -71,7 +71,7 @@ class NativeTrace : public ExeTracer
|
||||
protected:
|
||||
int fd;
|
||||
|
||||
ListenSocket native_listener;
|
||||
ListenSocketPtr native_listener;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -245,11 +245,12 @@ class TapListener
|
||||
void accept();
|
||||
|
||||
protected:
|
||||
ListenSocket listener;
|
||||
ListenSocketPtr listener;
|
||||
EtherTapStub *tap;
|
||||
|
||||
public:
|
||||
TapListener(EtherTapStub *t, int p) : listener(t->name(), p), tap(t) {}
|
||||
TapListener(EtherTapStub *t, int p) :
|
||||
listener(listenSocketInetConfig(p).build(t->name())), tap(t) {}
|
||||
~TapListener() { delete event; }
|
||||
|
||||
void listen();
|
||||
@@ -258,9 +259,9 @@ class TapListener
|
||||
void
|
||||
TapListener::listen()
|
||||
{
|
||||
listener.listen();
|
||||
listener->listen();
|
||||
|
||||
event = new Event(this, listener.getfd(), POLLIN|POLLERR);
|
||||
event = new Event(this, listener->getfd(), POLLIN|POLLERR);
|
||||
pollQueue.schedule(event);
|
||||
}
|
||||
|
||||
@@ -272,10 +273,10 @@ TapListener::accept()
|
||||
// thread.
|
||||
EventQueue::ScopedMigration migrate(tap->eventQueue());
|
||||
|
||||
if (!listener.islistening())
|
||||
if (!listener->islistening())
|
||||
panic("TapListener(accept): cannot accept if we're not listening!");
|
||||
|
||||
int sfd = listener.accept();
|
||||
int sfd = listener->accept();
|
||||
if (sfd != -1)
|
||||
tap->attach(sfd);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,8 @@ Terminal::DataEvent::process(int revent)
|
||||
*/
|
||||
Terminal::Terminal(const Params &p)
|
||||
: SerialDevice(p), listenEvent(NULL), dataEvent(NULL),
|
||||
number(p.number), data_fd(-1), listener(p.name, p.port),
|
||||
number(p.number), data_fd(-1),
|
||||
listener(listenSocketInetConfig(p.port).build(p.name)),
|
||||
txbuf(16384), rxbuf(16384), outfile(terminalDump(p))
|
||||
#if TRACING_ON == 1
|
||||
, linebuf(16384)
|
||||
@@ -175,19 +176,19 @@ Terminal::listen()
|
||||
return;
|
||||
}
|
||||
|
||||
listener.listen();
|
||||
listener->listen();
|
||||
|
||||
listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
|
||||
listenEvent = new ListenEvent(this, listener->getfd(), POLLIN);
|
||||
pollQueue.schedule(listenEvent);
|
||||
}
|
||||
|
||||
void
|
||||
Terminal::accept()
|
||||
{
|
||||
if (!listener.islistening())
|
||||
if (!listener->islistening())
|
||||
panic("%s: cannot accept a connection if not listening!", name());
|
||||
|
||||
int fd = listener.accept();
|
||||
int fd = listener->accept();
|
||||
if (data_fd != -1) {
|
||||
char message[] = "terminal already attached!\n";
|
||||
atomic_write(fd, message, sizeof(message));
|
||||
|
||||
@@ -101,7 +101,7 @@ class Terminal : public SerialDevice
|
||||
OutputStream * terminalDump(const TerminalParams &p);
|
||||
|
||||
protected:
|
||||
ListenSocket listener;
|
||||
ListenSocketPtr listener;
|
||||
|
||||
void listen();
|
||||
void accept();
|
||||
|
||||
Reference in New Issue
Block a user