base,cpu,dev,sim: Pull common logic into ListenSocket::listen().

Create a version of listen() which handles common logic internally,
including scanning for an available port number, and notifying what
port was chosen.

The port is managed internal to ListenSocket, so that the logic
interacting with it doesn't need to manually manage a port number, and
hence a port number does not need to exist for non AF_INET sockets.

Change-Id: Ie371eccc4d0da5e7b90714508e4cb72fb0091875
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69160
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Yu-hsin Wang <yuhsingw@google.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
This commit is contained in:
Gabe Black
2023-03-18 08:12:56 -07:00
committed by Gabe Black
parent 461520d0ab
commit 67fb75d659
11 changed files with 64 additions and 60 deletions

View File

@@ -392,7 +392,7 @@ std::map<Addr, HardBreakpoint *> hardBreakMap;
BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) :
incomingConnectionEvent(nullptr), incomingDataEvent(nullptr),
_port(_port), fd(-1), sys(_system),
listener(_system->name() + ".remote_gdb", _port), fd(-1), sys(_system),
connectEvent(*this), disconnectEvent(*this), trapEvent(this),
singleStepEvent(*this)
{}
@@ -417,17 +417,14 @@ BaseRemoteGDB::listen()
return;
}
while (!listener.listen(_port)) {
DPRINTF(GDBMisc, "Can't bind port %d\n", _port);
_port++;
}
listener.listen();
incomingConnectionEvent =
new IncomingConnectionEvent(this, listener.getfd(), POLLIN);
pollQueue.schedule(incomingConnectionEvent);
ccprintf(std::cerr, "%d: %s: listening for remote gdb on port %d\n",
curTick(), name(), _port);
ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n",
curTick(), name(), listener);
}
void
@@ -448,12 +445,12 @@ BaseRemoteGDB::connect()
}
}
int
BaseRemoteGDB::port() const
const ListenSocket &
BaseRemoteGDB::hostSocket() const
{
panic_if(!listener.islistening(),
"Remote GDB port is unknown until listen() has been called.\n");
return _port;
"Remote GDB socket is unknown until listen() has been called.");
return listener;
}
void

View File

@@ -161,7 +161,7 @@ class BaseRemoteGDB
void listen();
void connect();
int port() const;
const ListenSocket &hostSocket() const;
void attach(int fd);
void detach();
@@ -232,7 +232,6 @@ class BaseRemoteGDB
IncomingDataEvent *incomingDataEvent;
ListenSocket listener;
int _port;
// The socket commands come in through.
int fd;

View File

@@ -173,10 +173,12 @@ ListenSocket::acceptCloexec(int sockfd, struct sockaddr *addr,
//
//
ListenSocket::ListenSocket()
: listening(false), fd(-1)
ListenSocket::ListenSocket(const std::string &_name, int port)
: Named(_name), listening(false), fd(-1), _port(port)
{}
ListenSocket::ListenSocket() : ListenSocket("<unnammed>", -1) {}
ListenSocket::~ListenSocket()
{
if (fd != -1)
@@ -231,6 +233,23 @@ ListenSocket::listen(int port)
return true;
}
void
ListenSocket::listen()
{
while (!listen(_port)) {
_port++;
fatal_if(_port > 65536, "%s: cannot find an available port.", name());
}
ccprintf(std::cerr, "%s: Listening for connections on %s\n",
name(), *this);
}
void
ListenSocket::output(std::ostream &os) const
{
os << "port " << _port;
}
// Open a connection. Accept will block, so if you don't want it to,
// make sure a connection is ready before you call accept.

View File

@@ -35,6 +35,8 @@
#include <string>
#include "base/named.hh"
namespace gem5
{
@@ -69,7 +71,7 @@ struct UnixSocketAddr
std::string formattedPath;
};
class ListenSocket
class ListenSocket : public Named
{
protected:
/**
@@ -90,6 +92,7 @@ class ListenSocket
protected:
bool listening;
int fd;
int _port;
/*
* cleanup resets the static variables back to their default values.
@@ -101,12 +104,16 @@ class ListenSocket
* @ingroup api_socket
* @{
*/
ListenSocket(const std::string &_name, int port);
ListenSocket();
virtual ~ListenSocket();
virtual int accept();
virtual bool listen(int port);
virtual void listen();
virtual void output(std::ostream &os) const;
int getfd() const { return fd; }
bool islistening() const { return listening; }
@@ -119,6 +126,13 @@ class ListenSocket
/** @} */ // end of api_socket
};
inline static std::ostream &
operator << (std::ostream &os, const ListenSocket &socket)
{
socket.output(os);
return os;
}
} // namespace gem5
#endif //__SOCKET_HH__

View File

@@ -117,11 +117,11 @@ VncServer::DataEvent::process(int revent)
*/
VncServer::VncServer(const Params &p)
: VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number),
dataFd(-1), sendUpdate(false),
listener(p.name, p.port), sendUpdate(false),
supportsRawEnc(false), supportsResizeEnc(false)
{
if (p.port)
listen(p.port);
listen();
curState = WaitForProtocolVersion;
@@ -157,22 +157,14 @@ VncServer::~VncServer()
//socket creation and vnc client attach
void
VncServer::listen(int port)
VncServer::listen()
{
if (ListenSocket::allDisabled()) {
warn_once("Sockets disabled, not accepting vnc client connections");
return;
}
while (!listener.listen(port)) {
DPRINTF(VNC,
"can't bind address vnc server port %d in use PID %d\n",
port, getpid());
port++;
}
ccprintf(std::cerr, "%s: Listening for connections on port %d\n",
name(), port);
listener.listen();
listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
pollQueue.schedule(listenEvent);

View File

@@ -182,7 +182,7 @@ class VncServer : public VncInput
ListenSocket listener;
void listen(int port);
void listen();
void accept();
void data();
void detach();

View File

@@ -39,17 +39,13 @@ namespace gem5
namespace trace {
NativeTrace::NativeTrace(const Params &p)
: ExeTracer(p)
: ExeTracer(p), native_listener(p.name, 8000)
{
if (ListenSocket::allDisabled())
fatal("All listeners are disabled!");
int port = 8000;
while (!native_listener.listen(port)) {
DPRINTF(GDBMisc, "Can't bind port %d\n", port);
port++;
}
ccprintf(std::cerr, "Listening for native process on port %d\n", port);
native_listener.listen();
fd = native_listener.accept();
}

View File

@@ -240,17 +240,16 @@ class TapListener
};
friend class Event;
Event *event;
Event *event = nullptr;
void accept();
protected:
ListenSocket listener;
EtherTapStub *tap;
int port;
public:
TapListener(EtherTapStub *t, int p) : event(NULL), tap(t), port(p) {}
TapListener(EtherTapStub *t, int p) : listener(t->name(), p), tap(t) {}
~TapListener() { delete event; }
void listen();
@@ -259,12 +258,8 @@ class TapListener
void
TapListener::listen()
{
while (!listener.listen(port)) {
DPRINTF(Ethernet, "TapListener(listen): Can't bind port %d\n", port);
port++;
}
listener.listen();
ccprintf(std::cerr, "Listening for tap connection on port %d\n", port);
event = new Event(this, listener.getfd(), POLLIN|POLLERR);
pollQueue.schedule(event);
}

View File

@@ -121,8 +121,8 @@ Terminal::DataEvent::process(int revent)
*/
Terminal::Terminal(const Params &p)
: SerialDevice(p), listenEvent(NULL), dataEvent(NULL),
number(p.number), data_fd(-1), txbuf(16384), rxbuf(16384),
outfile(terminalDump(p))
number(p.number), data_fd(-1), listener(p.name, p.port),
txbuf(16384), rxbuf(16384), outfile(terminalDump(p))
#if TRACING_ON == 1
, linebuf(16384)
#endif
@@ -131,7 +131,7 @@ Terminal::Terminal(const Params &p)
outfile->stream()->setf(std::ios::unitbuf);
if (p.port)
listen(p.port);
listen();
}
Terminal::~Terminal()
@@ -168,22 +168,14 @@ Terminal::terminalDump(const TerminalParams &p)
//
void
Terminal::listen(int port)
Terminal::listen()
{
if (ListenSocket::allDisabled()) {
warn_once("Sockets disabled, not accepting terminal connections");
return;
}
while (!listener.listen(port)) {
DPRINTF(Terminal,
": can't bind address terminal port %d inuse PID %d\n",
port, getpid());
port++;
}
ccprintf(std::cerr, "%s: Listening for connections on port %d\n",
name(), port);
listener.listen();
listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
pollQueue.schedule(listenEvent);

View File

@@ -103,7 +103,7 @@ class Terminal : public SerialDevice
protected:
ListenSocket listener;
void listen(int port);
void listen();
void accept();
protected:

View File

@@ -97,8 +97,8 @@ Workload::startup()
// Now that we're about to start simulation, wait for GDB connections if
// requested.
if (gdb && waitForRemoteGDB) {
inform("%s: Waiting for a remote GDB connection on port %d.", name(),
gdb->port());
inform("%s: Waiting for a remote GDB connection on %s.", name(),
gdb->hostSocket());
gdb->connect();
}
}