diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index c8cb32fd71..095b2bd38c 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -392,10 +392,11 @@ std::map 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(); } diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 60a0d6a1eb..9f09582721 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -231,7 +231,7 @@ class BaseRemoteGDB IncomingConnectionEvent *incomingConnectionEvent; IncomingDataEvent *incomingDataEvent; - ListenSocket listener; + ListenSocketPtr listener; // The socket commands come in through. int fd; diff --git a/src/base/socket.cc b/src/base/socket.cc index 1aff73a7ff..5fb8492d50 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -269,4 +269,12 @@ ListenSocket::accept() return sfd; } +ListenSocketConfig +listenSocketInetConfig(int port) +{ + return ListenSocketConfig([port](const std::string &name) { + return std::make_unique(name, port); + }); +} + } // namespace gem5 diff --git a/src/base/socket.hh b/src/base/socket.hh index 81f4d6252f..638ce40f57 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -33,6 +33,9 @@ #include #include +#include +#include +#include #include #include "base/named.hh" @@ -127,6 +130,33 @@ class ListenSocket : public Named /** @} */ // end of api_socket }; +using ListenSocketPtr = std::unique_ptr; + +class ListenSocketConfig +{ + public: + using Builder = std::function; + + 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) { diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index 2d32cef8bb..4e5c951191 100644 --- a/src/base/vnc/vncserver.cc +++ b/src/base/vnc/vncserver.cc @@ -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; diff --git a/src/base/vnc/vncserver.hh b/src/base/vnc/vncserver.hh index 7455799025..d493c05a47 100644 --- a/src/base/vnc/vncserver.hh +++ b/src/base/vnc/vncserver.hh @@ -180,7 +180,7 @@ class VncServer : public VncInput int number; int dataFd; // data stream file describer - ListenSocket listener; + ListenSocketPtr listener; void listen(); void accept(); diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc index 05fb41b3a5..3070205b9f 100644 --- a/src/cpu/nativetrace.cc +++ b/src/cpu/nativetrace.cc @@ -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 diff --git a/src/cpu/nativetrace.hh b/src/cpu/nativetrace.hh index a00e97a18e..a19acaca3f 100644 --- a/src/cpu/nativetrace.hh +++ b/src/cpu/nativetrace.hh @@ -71,7 +71,7 @@ class NativeTrace : public ExeTracer protected: int fd; - ListenSocket native_listener; + ListenSocketPtr native_listener; public: diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc index 587dba5021..7c7a8dcb11 100644 --- a/src/dev/net/ethertap.cc +++ b/src/dev/net/ethertap.cc @@ -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); } diff --git a/src/dev/serial/terminal.cc b/src/dev/serial/terminal.cc index 02052b5e1a..6e8e435b07 100644 --- a/src/dev/serial/terminal.cc +++ b/src/dev/serial/terminal.cc @@ -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)); diff --git a/src/dev/serial/terminal.hh b/src/dev/serial/terminal.hh index bd6711da8a..03adc9f965 100644 --- a/src/dev/serial/terminal.hh +++ b/src/dev/serial/terminal.hh @@ -101,7 +101,7 @@ class Terminal : public SerialDevice OutputStream * terminalDump(const TerminalParams &p); protected: - ListenSocket listener; + ListenSocketPtr listener; void listen(); void accept();