Make Socket noncopyable, without inheritance.

This commit is contained in:
Relintai 2022-02-09 23:48:12 +01:00
parent 0e6ad2d135
commit 94fd22eee9

View File

@ -16,7 +16,6 @@
#pragma once #pragma once
#include <trantor/utils/NonCopyable.h>
#include "core/net/inet_address.h" #include "core/net/inet_address.h"
#include <trantor/utils/Logger.h> #include <trantor/utils/Logger.h>
#include <string> #include <string>
@ -25,13 +24,19 @@
#endif #endif
#include <fcntl.h> #include <fcntl.h>
namespace trantor namespace trantor {
{ class Socket {
class Socket : NonCopyable
{ protected:
public: // NonCopyable
static int createNonblockingSocketOrDie(int family) Socket(const Socket &) = delete;
{ Socket &operator=(const Socket &) = delete;
// some uncopyable classes maybe support move constructor....
Socket(Socket &&) noexcept(true) = default;
Socket &operator=(Socket &&) noexcept(true) = default;
public:
static int createNonblockingSocketOrDie(int family) {
#ifdef __linux__ #ifdef __linux__
int sock = ::socket(family, int sock = ::socket(family,
SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
@ -40,8 +45,7 @@ class Socket : NonCopyable
int sock = static_cast<int>(::socket(family, SOCK_STREAM, IPPROTO_TCP)); int sock = static_cast<int>(::socket(family, SOCK_STREAM, IPPROTO_TCP));
setNonBlockAndCloseOnExec(sock); setNonBlockAndCloseOnExec(sock);
#endif #endif
if (sock < 0) if (sock < 0) {
{
LOG_SYSERR << "sockets::createNonblockingOrDie"; LOG_SYSERR << "sockets::createNonblockingOrDie";
exit(1); exit(1);
} }
@ -49,8 +53,7 @@ class Socket : NonCopyable
return sock; return sock;
} }
static int getSocketError(int sockfd) static int getSocketError(int sockfd) {
{
int optval; int optval;
socklen_t optlen = static_cast<socklen_t>(sizeof optval); socklen_t optlen = static_cast<socklen_t>(sizeof optval);
#ifdef _WIN32 #ifdef _WIN32
@ -61,15 +64,12 @@ class Socket : NonCopyable
#endif #endif
{ {
return errno; return errno;
} } else {
else
{
return optval; return optval;
} }
} }
static int connect(int sockfd, const InetAddress &addr) static int connect(int sockfd, const InetAddress &addr) {
{
if (addr.isIpV6()) if (addr.isIpV6())
return ::connect(sockfd, return ::connect(sockfd,
addr.getSockAddr(), addr.getSockAddr(),
@ -84,8 +84,8 @@ class Socket : NonCopyable
static bool isSelfConnect(int sockfd); static bool isSelfConnect(int sockfd);
explicit Socket(int sockfd) : sockFd_(sockfd) explicit Socket(int sockfd) :
{ sockFd_(sockfd) {
} }
~Socket(); ~Socket();
/// abort if address in use /// abort if address in use
@ -95,8 +95,7 @@ class Socket : NonCopyable
int accept(InetAddress *peeraddr); int accept(InetAddress *peeraddr);
void closeWrite(); void closeWrite();
int read(char *buffer, uint64_t len); int read(char *buffer, uint64_t len);
int fd() int fd() {
{
return sockFd_; return sockFd_;
} }
static struct sockaddr_in6 getLocalAddr(int sockfd); static struct sockaddr_in6 getLocalAddr(int sockfd);
@ -123,19 +122,17 @@ class Socket : NonCopyable
void setKeepAlive(bool on); void setKeepAlive(bool on);
int getSocketError(); int getSocketError();
protected: protected:
int sockFd_; int sockFd_;
public: public:
// taken from muduo // taken from muduo
static void setNonBlockAndCloseOnExec(int sockfd) static void setNonBlockAndCloseOnExec(int sockfd) {
{
#ifdef _WIN32 #ifdef _WIN32
// TODO how to set FD_CLOEXEC on windows? is it necessary? // TODO how to set FD_CLOEXEC on windows? is it necessary?
u_long arg = 1; u_long arg = 1;
auto ret = ioctlsocket(sockfd, (long)FIONBIO, &arg); auto ret = ioctlsocket(sockfd, (long)FIONBIO, &arg);
if (ret) if (ret) {
{
LOG_ERROR << "ioctlsocket error"; LOG_ERROR << "ioctlsocket error";
} }
#else #else