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:
@@ -392,7 +392,7 @@ std::map<Addr, HardBreakpoint *> hardBreakMap;
|
|||||||
|
|
||||||
BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) :
|
BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) :
|
||||||
incomingConnectionEvent(nullptr), incomingDataEvent(nullptr),
|
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),
|
connectEvent(*this), disconnectEvent(*this), trapEvent(this),
|
||||||
singleStepEvent(*this)
|
singleStepEvent(*this)
|
||||||
{}
|
{}
|
||||||
@@ -417,17 +417,14 @@ BaseRemoteGDB::listen()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!listener.listen(_port)) {
|
listener.listen();
|
||||||
DPRINTF(GDBMisc, "Can't bind port %d\n", _port);
|
|
||||||
_port++;
|
|
||||||
}
|
|
||||||
|
|
||||||
incomingConnectionEvent =
|
incomingConnectionEvent =
|
||||||
new IncomingConnectionEvent(this, listener.getfd(), POLLIN);
|
new IncomingConnectionEvent(this, listener.getfd(), POLLIN);
|
||||||
pollQueue.schedule(incomingConnectionEvent);
|
pollQueue.schedule(incomingConnectionEvent);
|
||||||
|
|
||||||
ccprintf(std::cerr, "%d: %s: listening for remote gdb on port %d\n",
|
ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n",
|
||||||
curTick(), name(), _port);
|
curTick(), name(), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -448,12 +445,12 @@ BaseRemoteGDB::connect()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
const ListenSocket &
|
||||||
BaseRemoteGDB::port() const
|
BaseRemoteGDB::hostSocket() const
|
||||||
{
|
{
|
||||||
panic_if(!listener.islistening(),
|
panic_if(!listener.islistening(),
|
||||||
"Remote GDB port is unknown until listen() has been called.\n");
|
"Remote GDB socket is unknown until listen() has been called.");
|
||||||
return _port;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ class BaseRemoteGDB
|
|||||||
void listen();
|
void listen();
|
||||||
void connect();
|
void connect();
|
||||||
|
|
||||||
int port() const;
|
const ListenSocket &hostSocket() const;
|
||||||
|
|
||||||
void attach(int fd);
|
void attach(int fd);
|
||||||
void detach();
|
void detach();
|
||||||
@@ -232,7 +232,6 @@ class BaseRemoteGDB
|
|||||||
IncomingDataEvent *incomingDataEvent;
|
IncomingDataEvent *incomingDataEvent;
|
||||||
|
|
||||||
ListenSocket listener;
|
ListenSocket listener;
|
||||||
int _port;
|
|
||||||
|
|
||||||
// The socket commands come in through.
|
// The socket commands come in through.
|
||||||
int fd;
|
int fd;
|
||||||
|
|||||||
@@ -173,10 +173,12 @@ ListenSocket::acceptCloexec(int sockfd, struct sockaddr *addr,
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
ListenSocket::ListenSocket()
|
ListenSocket::ListenSocket(const std::string &_name, int port)
|
||||||
: listening(false), fd(-1)
|
: Named(_name), listening(false), fd(-1), _port(port)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
ListenSocket::ListenSocket() : ListenSocket("<unnammed>", -1) {}
|
||||||
|
|
||||||
ListenSocket::~ListenSocket()
|
ListenSocket::~ListenSocket()
|
||||||
{
|
{
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
@@ -231,6 +233,23 @@ ListenSocket::listen(int port)
|
|||||||
return true;
|
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,
|
// Open a connection. Accept will block, so if you don't want it to,
|
||||||
// make sure a connection is ready before you call accept.
|
// make sure a connection is ready before you call accept.
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "base/named.hh"
|
||||||
|
|
||||||
namespace gem5
|
namespace gem5
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -69,7 +71,7 @@ struct UnixSocketAddr
|
|||||||
std::string formattedPath;
|
std::string formattedPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ListenSocket
|
class ListenSocket : public Named
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@@ -90,6 +92,7 @@ class ListenSocket
|
|||||||
protected:
|
protected:
|
||||||
bool listening;
|
bool listening;
|
||||||
int fd;
|
int fd;
|
||||||
|
int _port;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cleanup resets the static variables back to their default values.
|
* cleanup resets the static variables back to their default values.
|
||||||
@@ -101,12 +104,16 @@ class ListenSocket
|
|||||||
* @ingroup api_socket
|
* @ingroup api_socket
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
ListenSocket(const std::string &_name, int port);
|
||||||
ListenSocket();
|
ListenSocket();
|
||||||
virtual ~ListenSocket();
|
virtual ~ListenSocket();
|
||||||
|
|
||||||
virtual int accept();
|
virtual int accept();
|
||||||
|
|
||||||
virtual bool listen(int port);
|
virtual bool listen(int port);
|
||||||
|
virtual void listen();
|
||||||
|
|
||||||
|
virtual void output(std::ostream &os) const;
|
||||||
|
|
||||||
int getfd() const { return fd; }
|
int getfd() const { return fd; }
|
||||||
bool islistening() const { return listening; }
|
bool islistening() const { return listening; }
|
||||||
@@ -119,6 +126,13 @@ class ListenSocket
|
|||||||
/** @} */ // end of api_socket
|
/** @} */ // end of api_socket
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline static std::ostream &
|
||||||
|
operator << (std::ostream &os, const ListenSocket &socket)
|
||||||
|
{
|
||||||
|
socket.output(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace gem5
|
} // namespace gem5
|
||||||
|
|
||||||
#endif //__SOCKET_HH__
|
#endif //__SOCKET_HH__
|
||||||
|
|||||||
@@ -117,11 +117,11 @@ VncServer::DataEvent::process(int revent)
|
|||||||
*/
|
*/
|
||||||
VncServer::VncServer(const Params &p)
|
VncServer::VncServer(const Params &p)
|
||||||
: VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number),
|
: VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number),
|
||||||
dataFd(-1), sendUpdate(false),
|
listener(p.name, p.port), sendUpdate(false),
|
||||||
supportsRawEnc(false), supportsResizeEnc(false)
|
supportsRawEnc(false), supportsResizeEnc(false)
|
||||||
{
|
{
|
||||||
if (p.port)
|
if (p.port)
|
||||||
listen(p.port);
|
listen();
|
||||||
|
|
||||||
curState = WaitForProtocolVersion;
|
curState = WaitForProtocolVersion;
|
||||||
|
|
||||||
@@ -157,22 +157,14 @@ VncServer::~VncServer()
|
|||||||
|
|
||||||
//socket creation and vnc client attach
|
//socket creation and vnc client attach
|
||||||
void
|
void
|
||||||
VncServer::listen(int port)
|
VncServer::listen()
|
||||||
{
|
{
|
||||||
if (ListenSocket::allDisabled()) {
|
if (ListenSocket::allDisabled()) {
|
||||||
warn_once("Sockets disabled, not accepting vnc client connections");
|
warn_once("Sockets disabled, not accepting vnc client connections");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!listener.listen(port)) {
|
listener.listen();
|
||||||
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);
|
|
||||||
|
|
||||||
listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
|
listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
|
||||||
pollQueue.schedule(listenEvent);
|
pollQueue.schedule(listenEvent);
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ class VncServer : public VncInput
|
|||||||
|
|
||||||
ListenSocket listener;
|
ListenSocket listener;
|
||||||
|
|
||||||
void listen(int port);
|
void listen();
|
||||||
void accept();
|
void accept();
|
||||||
void data();
|
void data();
|
||||||
void detach();
|
void detach();
|
||||||
|
|||||||
@@ -39,17 +39,13 @@ namespace gem5
|
|||||||
namespace trace {
|
namespace trace {
|
||||||
|
|
||||||
NativeTrace::NativeTrace(const Params &p)
|
NativeTrace::NativeTrace(const Params &p)
|
||||||
: ExeTracer(p)
|
: ExeTracer(p), native_listener(p.name, 8000)
|
||||||
{
|
{
|
||||||
if (ListenSocket::allDisabled())
|
if (ListenSocket::allDisabled())
|
||||||
fatal("All listeners are disabled!");
|
fatal("All listeners are disabled!");
|
||||||
|
|
||||||
int port = 8000;
|
native_listener.listen();
|
||||||
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);
|
|
||||||
fd = native_listener.accept();
|
fd = native_listener.accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,17 +240,16 @@ class TapListener
|
|||||||
};
|
};
|
||||||
|
|
||||||
friend class Event;
|
friend class Event;
|
||||||
Event *event;
|
Event *event = nullptr;
|
||||||
|
|
||||||
void accept();
|
void accept();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ListenSocket listener;
|
ListenSocket listener;
|
||||||
EtherTapStub *tap;
|
EtherTapStub *tap;
|
||||||
int port;
|
|
||||||
|
|
||||||
public:
|
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; }
|
~TapListener() { delete event; }
|
||||||
|
|
||||||
void listen();
|
void listen();
|
||||||
@@ -259,12 +258,8 @@ class TapListener
|
|||||||
void
|
void
|
||||||
TapListener::listen()
|
TapListener::listen()
|
||||||
{
|
{
|
||||||
while (!listener.listen(port)) {
|
listener.listen();
|
||||||
DPRINTF(Ethernet, "TapListener(listen): Can't bind port %d\n", port);
|
|
||||||
port++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ccprintf(std::cerr, "Listening for tap connection on port %d\n", port);
|
|
||||||
event = new Event(this, listener.getfd(), POLLIN|POLLERR);
|
event = new Event(this, listener.getfd(), POLLIN|POLLERR);
|
||||||
pollQueue.schedule(event);
|
pollQueue.schedule(event);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ Terminal::DataEvent::process(int revent)
|
|||||||
*/
|
*/
|
||||||
Terminal::Terminal(const Params &p)
|
Terminal::Terminal(const Params &p)
|
||||||
: SerialDevice(p), listenEvent(NULL), dataEvent(NULL),
|
: SerialDevice(p), listenEvent(NULL), dataEvent(NULL),
|
||||||
number(p.number), data_fd(-1), txbuf(16384), rxbuf(16384),
|
number(p.number), data_fd(-1), listener(p.name, p.port),
|
||||||
outfile(terminalDump(p))
|
txbuf(16384), rxbuf(16384), outfile(terminalDump(p))
|
||||||
#if TRACING_ON == 1
|
#if TRACING_ON == 1
|
||||||
, linebuf(16384)
|
, linebuf(16384)
|
||||||
#endif
|
#endif
|
||||||
@@ -131,7 +131,7 @@ Terminal::Terminal(const Params &p)
|
|||||||
outfile->stream()->setf(std::ios::unitbuf);
|
outfile->stream()->setf(std::ios::unitbuf);
|
||||||
|
|
||||||
if (p.port)
|
if (p.port)
|
||||||
listen(p.port);
|
listen();
|
||||||
}
|
}
|
||||||
|
|
||||||
Terminal::~Terminal()
|
Terminal::~Terminal()
|
||||||
@@ -168,22 +168,14 @@ Terminal::terminalDump(const TerminalParams &p)
|
|||||||
//
|
//
|
||||||
|
|
||||||
void
|
void
|
||||||
Terminal::listen(int port)
|
Terminal::listen()
|
||||||
{
|
{
|
||||||
if (ListenSocket::allDisabled()) {
|
if (ListenSocket::allDisabled()) {
|
||||||
warn_once("Sockets disabled, not accepting terminal connections");
|
warn_once("Sockets disabled, not accepting terminal connections");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!listener.listen(port)) {
|
listener.listen();
|
||||||
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);
|
|
||||||
|
|
||||||
listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
|
listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
|
||||||
pollQueue.schedule(listenEvent);
|
pollQueue.schedule(listenEvent);
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class Terminal : public SerialDevice
|
|||||||
protected:
|
protected:
|
||||||
ListenSocket listener;
|
ListenSocket listener;
|
||||||
|
|
||||||
void listen(int port);
|
void listen();
|
||||||
void accept();
|
void accept();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ Workload::startup()
|
|||||||
// Now that we're about to start simulation, wait for GDB connections if
|
// Now that we're about to start simulation, wait for GDB connections if
|
||||||
// requested.
|
// requested.
|
||||||
if (gdb && waitForRemoteGDB) {
|
if (gdb && waitForRemoteGDB) {
|
||||||
inform("%s: Waiting for a remote GDB connection on port %d.", name(),
|
inform("%s: Waiting for a remote GDB connection on %s.", name(),
|
||||||
gdb->port());
|
gdb->hostSocket());
|
||||||
gdb->connect();
|
gdb->connect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user