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:
Gabe Black
2023-03-18 08:59:51 -07:00
committed by Gabe Black
parent 7c614d225b
commit d03bc9d33c
11 changed files with 76 additions and 38 deletions

View File

@@ -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();
}

View File

@@ -231,7 +231,7 @@ class BaseRemoteGDB
IncomingConnectionEvent *incomingConnectionEvent;
IncomingDataEvent *incomingDataEvent;
ListenSocket listener;
ListenSocketPtr listener;
// The socket commands come in through.
int fd;

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -180,7 +180,7 @@ class VncServer : public VncInput
int number;
int dataFd; // data stream file describer
ListenSocket listener;
ListenSocketPtr listener;
void listen();
void accept();

View File

@@ -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

View File

@@ -71,7 +71,7 @@ class NativeTrace : public ExeTracer
protected:
int fd;
ListenSocket native_listener;
ListenSocketPtr native_listener;
public:

View File

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

View File

@@ -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));

View File

@@ -101,7 +101,7 @@ class Terminal : public SerialDevice
OutputStream * terminalDump(const TerminalParams &p);
protected:
ListenSocket listener;
ListenSocketPtr listener;
void listen();
void accept();