From 4dcca5775616ada2796ff7f84c3a4843eee9b506 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 12 Mar 2020 17:38:45 +0000 Subject: [PATCH] Socket: Enable TCP_NODELAY DAP usually consists of small packet requests, with small packet responses. When there are many frequent, blocking requests made, Nagle's algorithm can dramatically limit the request->response rates. --- src/socket.cpp | 51 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/src/socket.cpp b/src/socket.cpp index 5cb8861..f78f17a 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -20,6 +20,7 @@ #else #include #include +#include #include #include #include @@ -74,22 +75,9 @@ class dap::Socket::Shared : public dap::ReaderWriter { if (info) { auto socket = ::socket(info->ai_family, info->ai_socktype, info->ai_protocol); - -#if !defined(_WIN32) - // Prevent sockets lingering after process termination, causing - // reconnection issues on the same port. - - int enable = 1; - setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)); - - struct { - int l_onoff; /* linger active */ - int l_linger; /* how many seconds to linger for */ - } linger = {false, 0}; - setsockopt(socket, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); -#endif // !defined(_WIN32) - - return std::make_shared(info, socket); + auto out = std::make_shared(info, socket); + out->setOptions(); + return out; } freeaddrinfo(info); @@ -108,6 +96,33 @@ class dap::Socket::Shared : public dap::ReaderWriter { SOCKET socket() { return sock.load(); } + void setOptions() { + SOCKET s = socket(); + if (s == InvalidSocket) { + return; + } + + int enable = 1; + +#if !defined(_WIN32) + // Prevent sockets lingering after process termination, causing + // reconnection issues on the same port. + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&enable, sizeof(enable)); + + struct { + int l_onoff; /* linger active */ + int l_linger; /* how many seconds to linger for */ + } linger = {false, 0}; + setsockopt(s, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)); +#endif // !defined(_WIN32) + + // Enable TCP_NODELAY. + // DAP usually consists of small packet requests, with small packet + // responses. When there are many frequent, blocking requests made, + // Nagle's algorithm can dramatically limit the request->response rates. + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&enable, sizeof(enable)); + } + // dap::ReaderWriter compliance bool isOpen() { SOCKET s = socket(); @@ -188,7 +203,9 @@ std::shared_ptr Socket::accept() const { if (shared) { SOCKET socket = shared->socket(); if (socket != InvalidSocket) { - return std::make_shared(::accept(socket, 0, 0)); + auto out = std::make_shared(::accept(socket, 0, 0)); + out->setOptions(); + return out; } }