Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d8fc2c8
docs(tasks): v1.x inventory, triage template, merge report; update ta…
Apr 4, 2026
611e653
fix(pattern): %z with UTC pattern time shows +00:00 (port v1 09a674b7)
Apr 4, 2026
3adc681
fix(os): Windows utc_minutes_offset via mktime/_mkgmtime (port v1 b65…
Apr 4, 2026
130c45d
test(timezone): POSIX TZ with DST rules; include fcntl in tcp_client_…
Apr 4, 2026
5cd8a3f
feat(tcp): connect timeouts and socket IO timeouts; ci: checkout@v6 (…
Apr 4, 2026
c298165
feat(dup_filter_sink): ctor with sink list (v1 45b67eee); add full v1…
Apr 4, 2026
ac6f64e
feat(level): case-insensitive level_from_str; cmake: BUILD_TYPE only …
Apr 4, 2026
ee477d5
v1 parity: MSVC UTF-8, ansicolor/syslog/os, getenv, triage docs
Apr 4, 2026
b55b01b
parity: ringbuffer zero capacity, utf8 assert; v1 triage sync
Apr 4, 2026
c38a8bb
docs(tasks): note regular commits and push after parity ports
Apr 4, 2026
5aa8021
parity: dup_filter_sink notification level from last duplicate (#3390)
Apr 4, 2026
a5644f8
parity: UWP getenv (WINAPI_FAMILY); triage fmt/cfg/no-except
Apr 4, 2026
46555e8
parity: qt_sinks sign casts (#3487); triage 9c582574 superseded
Apr 4, 2026
dc11176
parity: SPDLOG_NO_TZ_OFFSET (#3483); triage #3360 superseded
Apr 4, 2026
57f292c
triage: supersede 5931a3d6 ba508057 47b7e7c7 (already on v2 tree)
Apr 4, 2026
6541bc6
tasks: sync 5.1 triage counts (33 superseded, 65 pending)
Apr 4, 2026
35f2328
parity: MSVC/clang hygiene #3515–#3519 #3521; triage batch
Apr 4, 2026
7c415e4
parity: udp_sink const udp_sink_config& (#3520); triage fc7e9c87 1685…
Apr 4, 2026
c85d68c
parity: README fmt::format_to (#3259); triage 2670f47d d276069a 951c5b99
Apr 4, 2026
9d413dc
parity: lock rotate_now mutex (#3281); triage a2b42620 f355b3d5 d276069a
Apr 4, 2026
9af3bcc
parity: basic_file_sink::truncate (#3280); triage fwrite/fmt/test batch
Apr 4, 2026
dff6fa1
parity: test_sink/callback iterator cast (#3315); triage Catch2 #3038
Apr 4, 2026
0a9563c
parity: SPDLOG_WCHAR_CONSOLE WriteConsoleW path (#3092); triage b6da5944
Apr 4, 2026
aeb67cf
triage: v1 async_logger/thread_pool + fmt 11.1 batch (15 SHAs)
Apr 4, 2026
8927cd1
Port v1 TSAN CMake (#3237); close 3A triage (MDC N/A, fmt 5A)
Apr 4, 2026
7eeb158
docs(triage): note 3A table complete
Apr 4, 2026
eb76886
5A: bundle fmt 12.1.0 (match v1.x), FMT_INSTALL, MSVC /wd4834, find_d…
Apr 4, 2026
5938b23
docs(5.4): migration and release notes for v1 parity integration branch
Apr 4, 2026
9bcb3ec
docs: cross-link migration notes; refresh PRD/tasks/merge-report for …
Apr 4, 2026
bfa8e9a
revert: remove README and PRD cross-links to migration notes
Apr 4, 2026
0a128e7
docs(merge-report): audit — add 9fe79692 to ports table; fix 6004e3d1…
Apr 4, 2026
a7ecbd3
Remove tasks
Apr 4, 2026
5970380
PR comment fixes
Apr 5, 2026
67611ee
Fix small random issues
Apr 5, 2026
ee4ad02
Fix PR comments - un-remove the comment and allow any fmt library ver…
Apr 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
image: ${{ matrix.config.compiler == 'clang' && 'teeks99/clang-ubuntu' || matrix.config.compiler }}:${{ matrix.config.version }}
name: "${{ matrix.config.compiler}} ${{ matrix.config.version }} (C++${{ matrix.config.cppstd }} ${{ matrix.config.build_type }} ${{ matrix.config.asan == 'ON' && 'ASAN' || '' }}${{ matrix.config.tsan == 'ON' && 'TSAN' || '' }})"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setup
run: |
apt-get update
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: macOS-latest
name: "macOS Clang (C++17, Release)"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Build
run: |
mkdir -p build && cd build
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: CMake ${{ matrix.config.GENERATOR }} CXX=${{matrix.config.CXX_STANDARD}}
shell: pwsh
Expand Down Expand Up @@ -85,7 +85,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: CMake ${{ matrix.config.GENERATOR }} CXX=${{matrix.config.CXX_STANDARD}}
shell: pwsh
Expand Down
45 changes: 40 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Set default build to release
# ---------------------------------------------------------------------------------------
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose Release or Debug" FORCE)
# Set CMAKE_BUILD_TYPE only if this project is top-level (avoid overriding parent)
if ((DEFINED PROJECT_IS_TOP_LEVEL AND PROJECT_IS_TOP_LEVEL) OR
(NOT DEFINED PROJECT_IS_TOP_LEVEL AND CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR))
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose Release or Debug" FORCE)
endif ()
endif ()
# ---------------------------------------------------------------------------------------
# Compiler config
Expand Down Expand Up @@ -48,7 +52,11 @@ option(SPDLOG_BUILD_SHARED "Build shared library" OFF)
option(SPDLOG_BUILD_EXAMPLE "Build example" ${SPDLOG_MASTER_PROJECT})
option(SPDLOG_BUILD_TESTS "Build tests" OFF)
option(SPDLOG_BUILD_BENCH "Build benchmarks (Requires https://github.com/google/benchmark.git to be installed)" OFF)
option(SPDLOG_SANITIZE_ADDRESS "Enable address sanitizer in tests" OFF)
option(SPDLOG_SANITIZE_ADDRESS "Enable address sanitizer for the spdlog library and anything that links it" OFF)
option(SPDLOG_SANITIZE_THREAD "Enable thread sanitizer for the spdlog library and anything that links it" OFF)
if (SPDLOG_SANITIZE_ADDRESS AND SPDLOG_SANITIZE_THREAD)
message(FATAL_ERROR "SPDLOG_SANITIZE_ADDRESS and SPDLOG_SANITIZE_THREAD are mutually exclusive")
endif ()
option(SPDLOG_BUILD_WARNINGS "Enable compiler warnings" OFF)
option(SPDLOG_SYSTEM_INCLUDES "Include as system headers (skip for clang-tidy)." OFF)
option(SPDLOG_INSTALL "Generate the install target" ${SPDLOG_MASTER_PROJECT})
Expand All @@ -62,7 +70,16 @@ option(SPDLOG_PREVENT_CHILD_FD "Prevent from child processes to inherit log file
option(SPDLOG_NO_THREAD_ID "prevent spdlog from querying the thread id on each log call if thread id is not needed" OFF)
option(SPDLOG_DISABLE_GLOBAL_LOGGER "Disable global logger creation" OFF)
option(SPDLOG_NO_TLS "Disable thread local storage" OFF)
option(SPDLOG_NO_TZ_OFFSET "Omit %z timezone offset (use on platforms without tm_gmtoff / full offset)" OFF)
option(SPDLOG_TIDY "run clang-tidy" OFF)
set(SPDLOG_DEBUG_POSTFIX "-${SPDLOG_VERSION_MAJOR}.${SPDLOG_VERSION_MINOR}d" CACHE STRING
"Filename postfix for libraries in debug builds (empty string allowed)")
option(SPDLOG_MSVC_UTF8 "Enable/disable MSVC /utf-8 flag (recommended for fmt)" ON)
if (WIN32)
option(SPDLOG_WCHAR_CONSOLE "Decode UTF-8 and write with WriteConsoleW (Unicode console output)" OFF)
else ()
set(SPDLOG_WCHAR_CONSOLE OFF CACHE BOOL "non supported option" FORCE)
endif ()
if (SPDLOG_TIDY)
set(CMAKE_CXX_CLANG_TIDY "clang-tidy")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Expand Down Expand Up @@ -91,7 +108,7 @@ message(STATUS "spdlog fmt external: " ${SPDLOG_FMT_EXTERNAL})
# Find {fmt} library
# ---------------------------------------------------------------------------------------
if (SPDLOG_FMT_EXTERNAL)
find_package(fmt REQUIRED)
find_package(fmt REQUIRED CONFIG)
message(STATUS "Using external fmt lib version: ${fmt_VERSION}")
else ()
include(cmake/fmtlib.cmake)
Expand All @@ -105,6 +122,8 @@ find_package(Threads REQUIRED)
# ---------------------------------------------------------------------------------------
set(SPDLOG_HEADERS
"include/spdlog/common.h"
"include/spdlog/file_event_handlers.h"
"include/spdlog/filename_t.h"
"include/spdlog/formatter.h"
"include/spdlog/fwd.h"
"include/spdlog/logger.h"
Expand Down Expand Up @@ -227,11 +246,22 @@ target_include_directories(spdlog ${SPDLOG_INCLUDES_LEVEL} PUBLIC "$<BUILD_INTER
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
target_link_libraries(spdlog PUBLIC Threads::Threads)
target_link_libraries(spdlog PUBLIC fmt::fmt)
if (MSVC)
if (SPDLOG_MSVC_UTF8)
# Pass /utf-8 only for real MSVC (not clang-cl); see fmtlib and #3260.
target_compile_options(spdlog PUBLIC $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:MSVC>>:/utf-8>)
endif ()
endif ()
spdlog_enable_warnings(spdlog)
if (SPDLOG_SANITIZE_ADDRESS)
spdlog_enable_addr_sanitizer(spdlog)
elseif (SPDLOG_SANITIZE_THREAD)
spdlog_enable_thread_sanitizer(spdlog)
endif ()
set_target_properties(spdlog PROPERTIES VERSION ${SPDLOG_VERSION} SOVERSION
${SPDLOG_VERSION_MAJOR}.${SPDLOG_VERSION_MINOR})
set(SPDLOG_NAME spdlog-${SPDLOG_VERSION_MAJOR})
set_target_properties(spdlog PROPERTIES DEBUG_POSTFIX "-${SPDLOG_VERSION_MAJOR}.${SPDLOG_VERSION_MINOR}d")
set_target_properties(spdlog PROPERTIES DEBUG_POSTFIX "${SPDLOG_DEBUG_POSTFIX}")
# ---------------------------------------------------------------------------------------
# Set prefix and source group for visual studio
# ---------------------------------------------------------------------------------------
Expand All @@ -249,17 +279,22 @@ endif ()
# ---------------------------------------------------------------------------------------
# Private defines according to the options
# ---------------------------------------------------------------------------------------
set(SPDLOG_UTF8_TO_WCHAR_CONSOLE ${SPDLOG_WCHAR_CONSOLE})
foreach (SPDLOG_OPTION
SPDLOG_CLOCK_COARSE
SPDLOG_PREVENT_CHILD_FD
SPDLOG_NO_THREAD_ID
SPDLOG_DISABLE_GLOBAL_LOGGER
SPDLOG_NO_TLS
SPDLOG_FWRITE_UNLOCKED)
SPDLOG_FWRITE_UNLOCKED
SPDLOG_UTF8_TO_WCHAR_CONSOLE)
if (${SPDLOG_OPTION})
target_compile_definitions(spdlog PRIVATE ${SPDLOG_OPTION})
endif ()
endforeach ()
if (SPDLOG_NO_TZ_OFFSET)
target_compile_definitions(spdlog PUBLIC SPDLOG_NO_TZ_OFFSET)
endif ()
# ---------------------------------------------------------------------------------------
# Build binaries
# ---------------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ see example [CMakeLists.txt](https://github.com/gabime/spdlog/blob/v2.x/example/
## Features
* Very fast (see [benchmarks](#benchmarks) below).
* Headers only or compiled
* Feature-rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library.
* Feature-rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library (bundled **12.1.0** by default; use `SPDLOG_FMT_EXTERNAL=ON` for a system **fmt**, **12.x** recommended).
* Asynchronous mode (optional)
* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting.
* Multi/Single threaded loggers.
Expand Down Expand Up @@ -258,7 +258,7 @@ struct fmt::formatter<my_type> : fmt::formatter<std::string>
{
auto format(my_type my, format_context &ctx) const -> decltype(ctx.out())
{
return format_to(ctx.out(), "[my_type i={}]", my.i);
return fmt::format_to(ctx.out(), "[my_type i={}]", my.i);
}
};

Expand Down
16 changes: 14 additions & 2 deletions cmake/fmtlib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,25 @@ include(FetchContent)
FetchContent_Declare(
fmt
DOWNLOAD_EXTRACT_TIMESTAMP FALSE
URL https://github.com/fmtlib/fmt/archive/refs/tags/11.1.4.tar.gz
URL_HASH SHA256=ac366b7b4c2e9f0dde63a59b3feb5ee59b67974b14ee5dc9ea8ad78aa2c1ee1e)
URL https://github.com/fmtlib/fmt/archive/refs/tags/12.1.0.tar.gz
URL_HASH SHA256=ea7de4299689e12b6dddd392f9896f08fb0777ac7168897a244a6d6085043fea)

FetchContent_GetProperties(fmt)
if(NOT fmt_POPULATED)
# We do not require os features of fmt
set(FMT_OS OFF CACHE BOOL "Disable FMT_OS" FORCE)
# fmt 12+ defaults FMT_INSTALL to OFF when built as a subproject; spdlog's
# install(EXPORT) requires fmt to participate in an export set (CMake 3.23+).
# Only enable fmt's install rules when spdlog installs
if(SPDLOG_INSTALL)
set(FMT_INSTALL ON CACHE BOOL "Generate the install target." FORCE)
else()
set(FMT_INSTALL OFF CACHE BOOL "Generate the install target." FORCE)
endif()
FetchContent_MakeAvailable(fmt)
set_target_properties(fmt PROPERTIES FOLDER "third-party")
# fmt 12.1.0: MSVC C4834 on locale_ref ctor (discarded [[nodiscard]] from isalpha); fixed on fmt master after 12.1.0.
if (MSVC)
target_compile_options(fmt PRIVATE /wd4834)
endif ()
endif()
2 changes: 1 addition & 1 deletion cmake/spdlogCPack.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
set(CPACK_RPM_PACKAGE_URL ${CPACK_PROJECT_URL})
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PROJECT_URL})
set(CPACK_RPM_PACKAGE_DESCRIPTION "Fast C++ logging library.")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "FastC++ logging library.")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Fast C++ logging library.")

if(CPACK_PACKAGE_NAME)
set(CPACK_RPM_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
Expand Down
2 changes: 1 addition & 1 deletion cmake/spdlogConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ include(CMakeFindDependencyMacro)

find_package(Threads REQUIRED)

find_dependency(fmt 11 CONFIG)
find_dependency(fmt CONFIG)

set(config_targets_file @config_targets_file@)
include("${CMAKE_CURRENT_LIST_DIR}/${config_targets_file}")
Expand Down
8 changes: 4 additions & 4 deletions example/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,15 @@ void multi_sink_example() {

// User defined types logging
struct my_type {
int i = 0;
explicit my_type(int i)
: i(i) {}
int value_ = 0;
explicit my_type(int value)
: value_(value) {}
};

template <>
struct fmt::formatter<my_type> : fmt::formatter<std::string> {
auto format(my_type my, format_context &ctx) const -> decltype(ctx.out()) {
return fmt::format_to(ctx.out(), "[my_type i={}]", my.i);
return fmt::format_to(ctx.out(), "[my_type value={}]", my.value_);
}
};

Expand Down
2 changes: 2 additions & 0 deletions include/spdlog/details/circular_q.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <cassert>
#include <vector>

#include <spdlog/common.h>

namespace spdlog {
namespace details {
template <typename T>
Expand Down
4 changes: 2 additions & 2 deletions include/spdlog/details/mpmc_blocking_q.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

// multi producer-multi consumer blocking queue.
// enqueue(..) - will block until room found to put the new message.
// enqueue_nowait(..) - will return immediately with false if no room left in
// the queue.
// enqueue_nowait(..) - enqueue immediately; overruns oldest message if no
// room left.
// dequeue_for(..) - will block until the queue is not empty or timeout have
// passed.

Expand Down
2 changes: 1 addition & 1 deletion include/spdlog/details/null_mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct null_mutex {

template <typename T>
struct null_atomic {
T value;
T value{};

null_atomic() = default;

Expand Down
2 changes: 1 addition & 1 deletion include/spdlog/details/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t
// Return file size according to open FILE* object
SPDLOG_API size_t filesize(FILE *f);

// Return utc offset in minutes or throw spdlog_ex on failure
// Return utc offset in minutes (0 on failure to compute offset)
SPDLOG_API int utc_minutes_offset(const std::tm &tm = details::os::localtime());

// Return current thread id as size_t
Expand Down
82 changes: 79 additions & 3 deletions include/spdlog/details/tcp_client_unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>

#include <cerrno>
#include <string>

#include "../common.h"
Expand All @@ -40,8 +44,67 @@ class tcp_client_unix {

~tcp_client_unix() { close(); }

static int connect_socket_with_timeout(int sockfd,
const struct sockaddr *addr,
socklen_t addrlen,
const struct timeval &tv) {
if (tv.tv_sec == 0 && tv.tv_usec == 0) {
int rv = ::connect(sockfd, addr, addrlen);
if (rv < 0 && errno == EISCONN) {
return 0;
}
return rv;
}

int orig_flags = ::fcntl(sockfd, F_GETFL, 0);
if (orig_flags < 0) {
return -1;
}
if (::fcntl(sockfd, F_SETFL, orig_flags | O_NONBLOCK) < 0) {
return -1;
}

int rv = ::connect(sockfd, addr, addrlen);
if (rv == 0 || (rv < 0 && errno == EISCONN)) {
::fcntl(sockfd, F_SETFL, orig_flags);
return 0;
}
if (errno != EINPROGRESS) {
::fcntl(sockfd, F_SETFL, orig_flags);
return -1;
}

fd_set wfds;
FD_ZERO(&wfds);
FD_SET(sockfd, &wfds);

struct timeval tv_copy = tv;
rv = ::select(sockfd + 1, nullptr, &wfds, nullptr, &tv_copy);
if (rv <= 0) {
::fcntl(sockfd, F_SETFL, orig_flags);
if (rv == 0) {
errno = ETIMEDOUT;
}
return -1;
}

int so_error = 0;
socklen_t len = sizeof(so_error);
if (::getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len) < 0) {
::fcntl(sockfd, F_SETFL, orig_flags);
return -1;
}
::fcntl(sockfd, F_SETFL, orig_flags);
if (so_error != 0 && so_error != EISCONN) {
errno = so_error;
return -1;
}

return 0;
}

// try to connect or throw on failure
void connect(const std::string &host, int port) {
void connect(const std::string &host, int port, int timeout_ms = 0) {
close();
struct addrinfo hints {};
memset(&hints, 0, sizeof(struct addrinfo));
Expand All @@ -50,6 +113,11 @@ class tcp_client_unix {
hints.ai_flags = AI_NUMERICSERV; // port passed as as numeric value
hints.ai_protocol = 0;

const int validated_timeout_ms = timeout_ms > 0 ? timeout_ms : 0;
struct timeval tv;
tv.tv_sec = validated_timeout_ms / 1000;
tv.tv_usec = (validated_timeout_ms % 1000) * 1000;

auto port_str = std::to_string(port);
struct addrinfo *addrinfo_result;
auto rv = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &addrinfo_result);
Expand All @@ -70,8 +138,11 @@ class tcp_client_unix {
last_errno = errno;
continue;
}
rv = ::connect(socket_, rp->ai_addr, rp->ai_addrlen);
if (rv == 0) {
#ifndef SOCK_CLOEXEC
::fcntl(socket_, F_SETFD, FD_CLOEXEC);
#endif
if (connect_socket_with_timeout(socket_, rp->ai_addr, rp->ai_addrlen, tv) == 0) {
last_errno = 0;
break;
}
last_errno = errno;
Expand All @@ -83,6 +154,11 @@ class tcp_client_unix {
throw_spdlog_ex("::connect failed", last_errno);
}

if (validated_timeout_ms > 0) {
::setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
::setsockopt(socket_, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
}

// set TCP_NODELAY
int enable_flag = 1;
::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&enable_flag), sizeof(enable_flag));
Expand Down
Loading
Loading