gem5-dev@gem5.org

The gem5 Developer List

View all threads

[M] Change in gem5/gem5[develop]: base: Abstract the AF_INET-ness out of ListenSocket.

GB
Gabe Black (Gerrit)
Tue, Mar 21, 2023 10:53 PM

Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/69163?usp=email )

Change subject: base: Abstract the AF_INET-ness out of ListenSocket.
......................................................................

base: Abstract the AF_INET-ness out of ListenSocket.

Put them into a subclass called ListenSocketInet.

Change-Id: I035621463a7f799c1d36a500ed933dc056238e5e

M src/base/socket.cc
M src/base/socket.hh
M src/base/socket.test.cc
3 files changed, 67 insertions(+), 45 deletions(-)

diff --git a/src/base/socket.cc b/src/base/socket.cc
index 5fb8492..0324788 100644
--- a/src/base/socket.cc
+++ b/src/base/socket.cc
@@ -173,11 +173,7 @@
//
//

-ListenSocket::ListenSocket(const std::string &_name, int port)

  • : Named(_name), listening(false), fd(-1), _port(port)
    -{}

-ListenSocket::ListenSocket() : ListenSocket("<unnammed>", -1) {}
+ListenSocket::ListenSocket(const std::string &_name) : Named(_name) {}

ListenSocket::~ListenSocket()
{
@@ -185,9 +181,41 @@
close(fd);
}

+// Open a connection.  Accept will block, so if you don't want it to,
+// make sure a connection is ready before you call accept.
+int
+ListenSocket::accept()
+{

  • struct sockaddr_in sockaddr;
  • socklen_t slen = sizeof (sockaddr);
  • int sfd = acceptCloexec(fd, (struct sockaddr *)&sockaddr, &slen);
  • if (sfd == -1)
  •    return -1;
    
  • return sfd;
    +}

+ListenSocketInet::ListenSocketInet(const std::string &_name, int port)

  • : ListenSocket(_name), _port(port)
    +{}

+int
+ListenSocketInet::accept()
+{

  • int sfd = ListenSocket::accept();
  • if (sfd == -1)
  •    return -1;
    
  • int i = 1;
  • int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
  • warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY
    failed!");
  • return sfd;
    +}
  • // Create a socket and configure it for listening
    bool
    -ListenSocket::listen(int port)
    +ListenSocketInet::listen(int port)
    {
    panic_if(listening, "Socket already listening!");

@@ -234,7 +262,7 @@
}

void
-ListenSocket::listen()
+ListenSocketInet::listen()
{
while (!listen(_port)) {
_port++;
@@ -245,35 +273,16 @@
}

void
-ListenSocket::output(std::ostream &os) const
+ListenSocketInet::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.
-int
-ListenSocket::accept()
-{

  • struct sockaddr_in sockaddr;
  • socklen_t slen = sizeof (sockaddr);
  • int sfd = acceptCloexec(fd, (struct sockaddr *)&sockaddr, &slen);
  • if (sfd == -1)
  •    return -1;
    
  • int i = 1;
  • int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
  • warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY
    failed!");
  • return sfd;
    -}
  • ListenSocketConfig
    listenSocketInetConfig(int port)
    {
    return ListenSocketConfig([port](const std::string &name) {
  •    return std::make_unique<ListenSocket>(name, port);
    
  •    return std::make_unique<ListenSocketInet>(name, port);
    });
    
    }

diff --git a/src/base/socket.hh b/src/base/socket.hh
index 638ce40..e233d85 100644
--- a/src/base/socket.hh
+++ b/src/base/socket.hh
@@ -93,31 +93,27 @@
static void loopbackOnly();

protected:
  • bool listening;
  • int fd;
  • int _port;
  • bool listening = false;

  • int fd = -1;

    /*

    • cleanup resets the static variables back to their default values.
      */
      static void cleanup();
  • virtual bool listen(int port);
  • ListenSocket(const std::string &_name);
public:
  /**
   * @ingroup api_socket
   * @{
   */
  • ListenSocket(const std::string &_name, int port);

  • ListenSocket();
    virtual ~ListenSocket();

    virtual int accept();

  • virtual void listen() = 0;
  • virtual void listen();
  • virtual void output(std::ostream &os) const;
  • virtual void output(std::ostream &os) const = 0;

    int getfd() const { return fd; }
    bool islistening() const { return listening; }
    @@ -130,6 +126,13 @@
    /** @} */ // end of api_socket
    };

+inline static std::ostream &
+operator << (std::ostream &os, const ListenSocket &socket)
+{

  • socket.output(os);

  • return os;
    +}

  • using ListenSocketPtr = std::unique_ptr<ListenSocket>;

    class ListenSocketConfig
    @@ -155,14 +158,24 @@

    static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; }

-ListenSocketConfig listenSocketInetConfig(int port);
+// AF_INET based sockets.

-inline static std::ostream &
-operator << (std::ostream &os, const ListenSocket &socket)
+class ListenSocketInet : public ListenSocket
{

  • socket.output(os);
  • return os;
    -}
  • protected:
  • int _port;
  • virtual bool listen(int port);
  • public:
  • ListenSocketInet(const std::string &_name, int port);
  • int accept() override;
  • void listen() override;
  • void output(std::ostream &os) const override;
    +};

+ListenSocketConfig listenSocketInetConfig(int port);

} // namespace gem5

diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc
index 8e1c25b..0f0de54 100644
--- a/src/base/socket.test.cc
+++ b/src/base/socket.test.cc
@@ -118,10 +118,10 @@
EXPECT_EQ(truncated_addr, sock_addr.formattedPath);
}

-class MockListenSocket : public ListenSocket
+class MockListenSocket : public ListenSocketInet
{
public:

  • MockListenSocket(int port) : ListenSocket("mock", port) {}
  • MockListenSocket(int port) : ListenSocketInet("mock", port) {}
    /*
    • This mock Listen Socket is used to ensure the static variables are
      reset
    • back to their default values after deconstruction (i.e., after a
      test

--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/69163?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I035621463a7f799c1d36a500ed933dc056238e5e
Gerrit-Change-Number: 69163
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black gabe.black@gmail.com
Gerrit-CC: Gabe Black gabeblack@google.com
Gerrit-MessageType: newchange

Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69163?usp=email ) Change subject: base: Abstract the AF_INET-ness out of ListenSocket. ...................................................................... base: Abstract the AF_INET-ness out of ListenSocket. Put them into a subclass called ListenSocketInet. Change-Id: I035621463a7f799c1d36a500ed933dc056238e5e --- M src/base/socket.cc M src/base/socket.hh M src/base/socket.test.cc 3 files changed, 67 insertions(+), 45 deletions(-) diff --git a/src/base/socket.cc b/src/base/socket.cc index 5fb8492..0324788 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -173,11 +173,7 @@ // // -ListenSocket::ListenSocket(const std::string &_name, int port) - : Named(_name), listening(false), fd(-1), _port(port) -{} - -ListenSocket::ListenSocket() : ListenSocket("<unnammed>", -1) {} +ListenSocket::ListenSocket(const std::string &_name) : Named(_name) {} ListenSocket::~ListenSocket() { @@ -185,9 +181,41 @@ close(fd); } +// Open a connection. Accept will block, so if you don't want it to, +// make sure a connection is ready before you call accept. +int +ListenSocket::accept() +{ + struct sockaddr_in sockaddr; + socklen_t slen = sizeof (sockaddr); + int sfd = acceptCloexec(fd, (struct sockaddr *)&sockaddr, &slen); + if (sfd == -1) + return -1; + + return sfd; +} + +ListenSocketInet::ListenSocketInet(const std::string &_name, int port) + : ListenSocket(_name), _port(port) +{} + +int +ListenSocketInet::accept() +{ + int sfd = ListenSocket::accept(); + if (sfd == -1) + return -1; + + int i = 1; + int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i)); + warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); + + return sfd; +} + // Create a socket and configure it for listening bool -ListenSocket::listen(int port) +ListenSocketInet::listen(int port) { panic_if(listening, "Socket already listening!"); @@ -234,7 +262,7 @@ } void -ListenSocket::listen() +ListenSocketInet::listen() { while (!listen(_port)) { _port++; @@ -245,35 +273,16 @@ } void -ListenSocket::output(std::ostream &os) const +ListenSocketInet::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. -int -ListenSocket::accept() -{ - struct sockaddr_in sockaddr; - socklen_t slen = sizeof (sockaddr); - int sfd = acceptCloexec(fd, (struct sockaddr *)&sockaddr, &slen); - if (sfd == -1) - return -1; - - int i = 1; - int ret = ::setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i)); - warn_if(ret < 0, "ListenSocket(accept): setsockopt() TCP_NODELAY failed!"); - - return sfd; -} - ListenSocketConfig listenSocketInetConfig(int port) { return ListenSocketConfig([port](const std::string &name) { - return std::make_unique<ListenSocket>(name, port); + return std::make_unique<ListenSocketInet>(name, port); }); } diff --git a/src/base/socket.hh b/src/base/socket.hh index 638ce40..e233d85 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -93,31 +93,27 @@ static void loopbackOnly(); protected: - bool listening; - int fd; - int _port; + bool listening = false; + int fd = -1; /* * cleanup resets the static variables back to their default values. */ static void cleanup(); - virtual bool listen(int port); + ListenSocket(const std::string &_name); public: /** * @ingroup api_socket * @{ */ - ListenSocket(const std::string &_name, int port); - ListenSocket(); virtual ~ListenSocket(); virtual int accept(); + virtual void listen() = 0; - virtual void listen(); - - virtual void output(std::ostream &os) const; + virtual void output(std::ostream &os) const = 0; int getfd() const { return fd; } bool islistening() const { return listening; } @@ -130,6 +126,13 @@ /** @} */ // end of api_socket }; +inline static std::ostream & +operator << (std::ostream &os, const ListenSocket &socket) +{ + socket.output(os); + return os; +} + using ListenSocketPtr = std::unique_ptr<ListenSocket>; class ListenSocketConfig @@ -155,14 +158,24 @@ static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; } -ListenSocketConfig listenSocketInetConfig(int port); +// AF_INET based sockets. -inline static std::ostream & -operator << (std::ostream &os, const ListenSocket &socket) +class ListenSocketInet : public ListenSocket { - socket.output(os); - return os; -} + protected: + int _port; + + virtual bool listen(int port); + + public: + ListenSocketInet(const std::string &_name, int port); + + int accept() override; + void listen() override; + void output(std::ostream &os) const override; +}; + +ListenSocketConfig listenSocketInetConfig(int port); } // namespace gem5 diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc index 8e1c25b..0f0de54 100644 --- a/src/base/socket.test.cc +++ b/src/base/socket.test.cc @@ -118,10 +118,10 @@ EXPECT_EQ(truncated_addr, sock_addr.formattedPath); } -class MockListenSocket : public ListenSocket +class MockListenSocket : public ListenSocketInet { public: - MockListenSocket(int port) : ListenSocket("mock", port) {} + MockListenSocket(int port) : ListenSocketInet("mock", port) {} /* * This mock Listen Socket is used to ensure the static variables are reset * back to their default values after deconstruction (i.e., after a test -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69163?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I035621463a7f799c1d36a500ed933dc056238e5e Gerrit-Change-Number: 69163 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black <gabe.black@gmail.com> Gerrit-CC: Gabe Black <gabeblack@google.com> Gerrit-MessageType: newchange