From bb8e30e6ba990f5c5f21ac0949e4a34a9a2c8d93 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Wed, 11 Jun 2025 14:49:56 +0200 Subject: [PATCH 01/46] Use new URL for libatomic_ops releases --- scripts/scons_helpers/build-3rdparty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/scons_helpers/build-3rdparty.py b/scripts/scons_helpers/build-3rdparty.py index c994b8247..2b552129f 100644 --- a/scripts/scons_helpers/build-3rdparty.py +++ b/scripts/scons_helpers/build-3rdparty.py @@ -1135,7 +1135,7 @@ def die(text, *args): elif ctx.pkg_name == 'libatomic_ops': download( ctx, - 'https://github.com/ivmai/libatomic_ops/releases/download/' + 'https://github.com/bdwgc/libatomic_ops/releases/download/' 'v{ctx.pkg_ver}/libatomic_ops-{ctx.pkg_ver}.tar.gz', 'libatomic_ops-{ctx.pkg_ver}.tar.gz') unpack(ctx, From b615df5094db09bcffc5b1a5e32f0d5abf9a9903 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Wed, 11 Jun 2025 19:40:39 +0200 Subject: [PATCH 02/46] socket_addr and _ops: use Winsock2 on Windows --- .../target_berkley/roc_address/socket_addr.h | 12 +++- .../target_berkley/roc_netio/socket_ops.cpp | 58 +++++++++++++++++-- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index 1db2959ed..a19786c86 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -12,8 +12,16 @@ #ifndef ROC_ADDRESS_SOCKET_ADDR_H_ #define ROC_ADDRESS_SOCKET_ADDR_H_ -#include -#include +#ifndef __WIN32__ + #include + #include +#else + #include + typedef uint16_t sa_family_t; + typedef uint16_t in_port_t; + #include + #include +#endif #include "roc_address/addr_family.h" #include "roc_core/attributes.h" diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index a01e09b1e..72c4264b3 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -8,10 +8,20 @@ #include #include -#include -#include + +#ifndef __WIN32__ + #include + #include + #include +#else + #include + typedef uint16_t sa_family_t; + typedef uint16_t in_port_t; + #include + #include +#endif + #include -#include #include #include #include @@ -98,7 +108,7 @@ bool get_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int& opt_val) { socklen_t opt_len = sizeof(opt_val); - if (getsockopt(sock, level, opt, &opt_val, &opt_len) == -1) { + if (getsockopt(sock, level, opt, (void*) &opt_val, &opt_len) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: getsockopt(%s): %s", opt_name, @@ -118,7 +128,7 @@ bool get_int_option( bool set_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int opt_val) { - if (setsockopt(sock, level, opt, &opt_val, sizeof(opt_val)) == -1) { + if (setsockopt(sock, level, opt, (void*) &opt_val, sizeof(opt_val)) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(%s): %s", opt_name, @@ -140,7 +150,10 @@ bool set_int_option( // creation and fcntl() call, during which fork() can be called from another thread // // - for performance reasons: without SOCK_CLOEXEC there are two more system calls + + bool set_cloexec(SocketHandle sock) { +#ifndef __WIN32__ // Probably no equivalent on Windows int flags; while ((flags = fcntl(sock, F_GETFD)) == -1) { @@ -167,9 +180,11 @@ bool set_cloexec(SocketHandle sock) { } } +#endif // ! __WIN32__ return true; } + #endif // !defined(SOCK_CLOEXEC) #if !defined(SOCK_NONBLOCK) @@ -178,6 +193,9 @@ bool set_cloexec(SocketHandle sock) { // // Using SOCK_NONBLOCK is preferred because of performance reasons. // Without SOCK_NONBLOCK there are two more system calls. + +#ifndef __WIN32__ + bool set_nonblock(SocketHandle sock) { int flags; @@ -208,6 +226,21 @@ bool set_nonblock(SocketHandle sock) { return true; } +#else // __WIN32__ + +bool set_nonblock(SocketHandle sock) { + int res; + unsigned long mode = 1; // 0 for blocking, nonzero for non blocking + + res = ioctlsocket(sock, FIONBIO, &mode); + //if (iResult != NO_ERROR) + //printf("ioctlsocket failed with error: %ld\n", iResult); + + return (res == NO_ERROR); +} + +#endif // __WIN32__ + #endif // !defined(SOCK_NONBLOCK) } // namespace @@ -434,6 +467,10 @@ bool socket_end_connect(SocketHandle sock) { return true; } +#ifdef __WIN32__ +#define MSG_DONTWAIT (0) // Eeek! but ok... +#endif + ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { roc_panic_if(sock < 0); roc_panic_if(!buf); @@ -540,6 +577,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { return 0; } +#ifndef __WIN32__ // Block SIGPIPE for this thread. // This works since kernel sends SIGPIPE to the thread that called send(), // not to the whole process. @@ -563,6 +601,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { if ((sigpipe_pending = sigismember(&sig_pending, SIGPIPE)) == -1) { roc_panic("socket: sigismember(): %s", core::errno_to_str().c_str()); } +#endif // !__WIN32__ ssize_t ret; while ((ret = send(sock, buf, bufsz, MSG_DONTWAIT)) == -1) { @@ -575,6 +614,8 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { const int saved_errno = errno; +#ifndef __WIN32__ + // If send() failed with EPIPE, and SIGPIPE was not already pending before calling // send(), then fetch SIGPIPE from pending signal mask. if (ret == -1 && saved_errno == EPIPE && sigpipe_pending == 0) { @@ -594,6 +635,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { if (int err = pthread_sigmask(SIG_SETMASK, &sig_restore, NULL)) { roc_panic("socket: pthread_sigmask(): %s", core::errno_to_str(err).c_str()); } +#endif // !__WIN32__ if (ret < 0 && is_ewouldblock(saved_errno)) { return SockErr_WouldBlock; @@ -653,6 +695,10 @@ ssize_t socket_try_send_to(SocketHandle sock, return ret; } +#ifdef __WIN32__ +#define SHUT_RDWR (SD_BOTH) +#endif + bool socket_shutdown(SocketHandle sock) { roc_panic_if(sock < 0); @@ -705,7 +751,7 @@ bool socket_close_with_reset(SocketHandle sock) { ling.l_linger = 0; bool setsockopt_failed = false; - if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)) == -1) { + if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*) &ling, sizeof(ling)) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(SO_LINGER): %s", From b9c0fc4dc5bfbbcc496783d109d4aacf9bc17186 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 12:17:23 +0200 Subject: [PATCH 03/46] socket_addr.cpp: ifdef out include arpa/inet.h for WIN32 --- .../roc_address/target_berkley/roc_address/socket_addr.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp index de3585886..b60dd5c5b 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp @@ -6,7 +6,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef __WIN32__ #include +#endif #include "roc_address/socket_addr.h" #include "roc_core/endian.h" From 2a48b4e47cf271083636223998fc0ba3faa0ec24 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 15:01:10 +0200 Subject: [PATCH 04/46] socket_addr/_ops: Formatting changes to comply with CI check --- .../target_berkley/roc_address/socket_addr.h | 16 ++++----- .../target_berkley/roc_netio/socket_ops.cpp | 36 +++++++++---------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index a19786c86..360119eb1 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -11,16 +11,16 @@ #ifndef ROC_ADDRESS_SOCKET_ADDR_H_ #define ROC_ADDRESS_SOCKET_ADDR_H_ +#ifndef ROC_ADDRESS_SOCKET_ADDR_H_ -#ifndef __WIN32__ - #include - #include +#include +#include #else - #include - typedef uint16_t sa_family_t; - typedef uint16_t in_port_t; - #include - #include +#include +typedef uint16_t sa_family_t; +typedef uint16_t in_port_t; +#include +#include #endif #include "roc_address/addr_family.h" diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 72c4264b3..00ebd8a07 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -10,15 +10,15 @@ #include #ifndef __WIN32__ - #include - #include - #include +#include +#include +#include #else - #include - typedef uint16_t sa_family_t; - typedef uint16_t in_port_t; - #include - #include +#include +typedef uint16_t sa_family_t; +typedef uint16_t in_port_t; +#include +#include #endif #include @@ -108,7 +108,7 @@ bool get_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int& opt_val) { socklen_t opt_len = sizeof(opt_val); - if (getsockopt(sock, level, opt, (void*) &opt_val, &opt_len) == -1) { + if (getsockopt(sock, level, opt, (void*)&opt_val, &opt_len) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: getsockopt(%s): %s", opt_name, @@ -128,7 +128,7 @@ bool get_int_option( bool set_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int opt_val) { - if (setsockopt(sock, level, opt, (void*) &opt_val, sizeof(opt_val)) == -1) { + if (setsockopt(sock, level, opt, (void*)&opt_val, sizeof(opt_val)) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(%s): %s", opt_name, @@ -151,7 +151,6 @@ bool set_int_option( // // - for performance reasons: without SOCK_CLOEXEC there are two more system calls - bool set_cloexec(SocketHandle sock) { #ifndef __WIN32__ // Probably no equivalent on Windows int flags; @@ -184,7 +183,6 @@ bool set_cloexec(SocketHandle sock) { return true; } - #endif // !defined(SOCK_CLOEXEC) #if !defined(SOCK_NONBLOCK) @@ -229,14 +227,14 @@ bool set_nonblock(SocketHandle sock) { #else // __WIN32__ bool set_nonblock(SocketHandle sock) { - int res; - unsigned long mode = 1; // 0 for blocking, nonzero for non blocking + int res; + unsigned long mode = 1; // 0 for blocking, nonzero for non blocking - res = ioctlsocket(sock, FIONBIO, &mode); - //if (iResult != NO_ERROR) - //printf("ioctlsocket failed with error: %ld\n", iResult); + ....res = ioctlsocket(sock, FIONBIO, &mode); + .... // if (iResult != NO_ERROR) + .... // printf("ioctlsocket failed with error: %ld\n", iResult); - return (res == NO_ERROR); + return (res == NO_ERROR); } #endif // __WIN32__ @@ -751,7 +749,7 @@ bool socket_close_with_reset(SocketHandle sock) { ling.l_linger = 0; bool setsockopt_failed = false; - if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*) &ling, sizeof(ling)) == -1) { + if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&ling, sizeof(ling)) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(SO_LINGER): %s", From 5ae92a1c6e80dc5724ba4979e7ce398ca8ee5aa0 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 15:04:42 +0200 Subject: [PATCH 05/46] Fix accidental delete of ifdef in previous commit --- .../roc_address/target_berkley/roc_address/socket_addr.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index 360119eb1..acf32d664 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -13,6 +13,7 @@ #define ROC_ADDRESS_SOCKET_ADDR_H_ #ifndef ROC_ADDRESS_SOCKET_ADDR_H_ +#ifndef __WIN32__ #include #include #else From 48918a054f4815a357767ad9d9cb8b38ce1cf828 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 15:11:24 +0200 Subject: [PATCH 06/46] Fix spurious ifdef, now it builds back on Debian... --- .../roc_address/target_berkley/roc_address/socket_addr.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index acf32d664..d3b37d083 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -11,7 +11,6 @@ #ifndef ROC_ADDRESS_SOCKET_ADDR_H_ #define ROC_ADDRESS_SOCKET_ADDR_H_ -#ifndef ROC_ADDRESS_SOCKET_ADDR_H_ #ifndef __WIN32__ #include From ad58a97c807e042b4734837951e348c414ef1492 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 18:02:08 +0200 Subject: [PATCH 07/46] splitter-comment in socket_addr.h for clang-format --- .../roc_address/target_berkley/roc_address/socket_addr.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index d3b37d083..e640e4918 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -12,16 +12,18 @@ #ifndef ROC_ADDRESS_SOCKET_ADDR_H_ #define ROC_ADDRESS_SOCKET_ADDR_H_ +// splitter comment for clang-format #ifndef __WIN32__ #include #include -#else +#else // __WIN32__ #include typedef uint16_t sa_family_t; typedef uint16_t in_port_t; #include #include -#endif +#endif // __WIN32__ +// splitter comment for clang-format #include "roc_address/addr_family.h" #include "roc_core/attributes.h" From 838cefbe618bd2c04eba32a586d70ee8112afcbd Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 19:17:21 +0200 Subject: [PATCH 08/46] include errno_to_str.h from wav_sink/source.cpp Linux build is fine, but MinGW build fails without those. --- src/internal_modules/roc_sndio/wav_sink.cpp | 1 + src/internal_modules/roc_sndio/wav_source.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/internal_modules/roc_sndio/wav_sink.cpp b/src/internal_modules/roc_sndio/wav_sink.cpp index b739e69a8..f40918422 100644 --- a/src/internal_modules/roc_sndio/wav_sink.cpp +++ b/src/internal_modules/roc_sndio/wav_sink.cpp @@ -11,6 +11,7 @@ #include "roc_audio/pcm_subformat.h" #include "roc_audio/sample_spec_to_str.h" #include "roc_core/endian_ops.h" +#include "roc_core/errno_to_str.h" #include "roc_core/log.h" #include "roc_core/panic.h" #include "roc_status/code_to_str.h" diff --git a/src/internal_modules/roc_sndio/wav_source.cpp b/src/internal_modules/roc_sndio/wav_source.cpp index 9c6516cc1..ee7e90f64 100644 --- a/src/internal_modules/roc_sndio/wav_source.cpp +++ b/src/internal_modules/roc_sndio/wav_source.cpp @@ -8,6 +8,7 @@ #include "roc_sndio/wav_source.h" #include "roc_audio/sample_spec_to_str.h" +#include "roc_core/errno_to_str.h" #include "roc_core/log.h" #include "roc_core/panic.h" #include "roc_status/code_to_str.h" From b2f6349332ec58a4faa110177090a332273ac46f Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 19:44:56 +0200 Subject: [PATCH 09/46] socket_ops.cpp: Remove spurious dots in a WIN32 section --- .../roc_netio/target_berkley/roc_netio/socket_ops.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 00ebd8a07..fc9f2cdbd 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -230,11 +230,11 @@ bool set_nonblock(SocketHandle sock) { int res; unsigned long mode = 1; // 0 for blocking, nonzero for non blocking - ....res = ioctlsocket(sock, FIONBIO, &mode); - .... // if (iResult != NO_ERROR) - .... // printf("ioctlsocket failed with error: %ld\n", iResult); + res = ioctlsocket(sock, FIONBIO, &mode); + // if (iResult != NO_ERROR) + // printf("ioctlsocket failed with error: %ld\n", iResult); - return (res == NO_ERROR); + return (res == NO_ERROR); } #endif // __WIN32__ From cd59a6d9985f65982667ed93c6f5085b2adbcb43 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 20:07:54 +0200 Subject: [PATCH 10/46] windows cond.cpp: fix local variable name mismatch --- src/internal_modules/roc_core/target_windows/roc_core/cond.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp b/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp index a2645933f..0e1e15f78 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp +++ b/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp @@ -34,7 +34,7 @@ bool Cond::timed_wait(nanoseconds_t timeout) const { if (err == ERROR_TIMEOUT || err == WAIT_TIMEOUT) { return false; } - roc_panic("cond: SleepConditionVariableCS(): error %lu", error); + roc_panic("cond: SleepConditionVariableCS(): error %lu", err); } return true; From 2ae2c27698eafdf171ae6e11adee607ff8dbf316 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 12 Jun 2025 20:12:34 +0200 Subject: [PATCH 11/46] windows errno_to_str.cpp: remove const from size local var --- .../roc_core/target_windows/roc_core/errno_to_str.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp b/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp index abc0e06e1..924d626f1 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp +++ b/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp @@ -23,7 +23,7 @@ errno_to_str::errno_to_str(int err) { void errno_to_str::format_(int err) { wchar_t wbuf[sizeof(buffer_)] = {}; - const size_t size = + size_t size = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), wbuf, sizeof(wbuf) / sizeof(wchar_t) - 1, nullptr); From c35008bc3cfb8ef2d188ee7714852dc52d81ae51 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Fri, 13 Jun 2025 18:40:06 +0200 Subject: [PATCH 12/46] Add/fix some else/endif ending comments --- .../roc_address/target_berkley/roc_address/socket_addr.h | 2 +- .../roc_netio/target_berkley/roc_netio/socket_ops.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index e640e4918..77401270c 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -16,7 +16,7 @@ #ifndef __WIN32__ #include #include -#else // __WIN32__ +#else // ! __WIN32__ #include typedef uint16_t sa_family_t; typedef uint16_t in_port_t; diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index fc9f2cdbd..04e74cf2b 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -13,13 +13,13 @@ #include #include #include -#else +#else // __WIN32__ #include typedef uint16_t sa_family_t; typedef uint16_t in_port_t; #include #include -#endif +#endif // ! __WIN32__ #include #include @@ -237,7 +237,7 @@ bool set_nonblock(SocketHandle sock) { return (res == NO_ERROR); } -#endif // __WIN32__ +#endif // ! __WIN32__ #endif // !defined(SOCK_NONBLOCK) From 8ec4723229d918a2ee0350118082e17a3aaee812 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 15 Jun 2025 00:56:06 +0200 Subject: [PATCH 13/46] socket_ops: fixes for MinGW build without -fpermissive --- .../target_berkley/roc_netio/socket_ops.cpp | 26 +++++++++++++------ .../target_berkley/roc_netio/socket_ops.h | 8 ++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 04e74cf2b..0421e70b8 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -31,6 +31,15 @@ typedef uint16_t in_port_t; #include "roc_core/panic.h" #include "roc_netio/socket_ops.h" +// To compile without -fpermissive +#ifndef __WIN32__ +typedef void os_buf_t; +typedef int os_val_t; +#else // __WIN32__ +typedef char os_buf_t; +typedef char os_val_t; +#endif // ! __WIN32__ + namespace roc { namespace netio { @@ -108,7 +117,7 @@ bool get_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int& opt_val) { socklen_t opt_len = sizeof(opt_val); - if (getsockopt(sock, level, opt, (void*)&opt_val, &opt_len) == -1) { + if (getsockopt(sock, level, opt, (os_val_t*)&opt_val, &opt_len) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: getsockopt(%s): %s", opt_name, @@ -128,7 +137,7 @@ bool get_int_option( bool set_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int opt_val) { - if (setsockopt(sock, level, opt, (void*)&opt_val, sizeof(opt_val)) == -1) { + if (setsockopt(sock, level, opt, (const os_val_t*)&opt_val, sizeof(opt_val)) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(%s): %s", opt_name, @@ -478,7 +487,7 @@ ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { } ssize_t ret; - while ((ret = recv(sock, buf, bufsz, MSG_DONTWAIT)) == -1) { + while ((ret = recv(sock, (os_buf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -527,7 +536,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { #endif ssize_t ret; - while ((ret = send(sock, buf, bufsz, flags)) == -1) { + while ((ret = send(sock, (const os_buf_t*)buf, bufsz, flags)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -602,7 +611,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { #endif // !__WIN32__ ssize_t ret; - while ((ret = send(sock, buf, bufsz, MSG_DONTWAIT)) == -1) { + while ((ret = send(sock, (os_buf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -663,8 +672,8 @@ ssize_t socket_try_send_to(SocketHandle sock, roc_panic_if(!remote_address.has_host_port()); ssize_t ret; - while ((ret = sendto(sock, buf, bufsz, MSG_DONTWAIT, remote_address.saddr(), - remote_address.slen())) + while ((ret = sendto(sock, (const os_buf_t*)buf, bufsz, MSG_DONTWAIT, + remote_address.saddr(), remote_address.slen())) == -1) { roc_panic_if(is_malformed(errno)); @@ -749,7 +758,8 @@ bool socket_close_with_reset(SocketHandle sock) { ling.l_linger = 0; bool setsockopt_failed = false; - if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&ling, sizeof(ling)) == -1) { + if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (const os_val_t*)&ling, sizeof(ling)) + == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(SO_LINGER): %s", diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h index 0abcd8bbc..9b6d247b3 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h @@ -48,10 +48,18 @@ enum SocketError { }; //! Platform-specific socket handle. +#ifndef __WIN32__ typedef int SocketHandle; +#else +typedef SOCKET SocketHandle; +#endif //! Invalid socket handle. +#ifndef __WIN32__ const SocketHandle SocketInvalid = -1; +#else +const SocketHandle SocketInvalid = INVALID_SOCKET; +#endif //! Create non-blocking socket. ROC_NODISCARD bool From 71a52499604b90c21dd4ee1a0772f77856310938 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 15 Jun 2025 03:14:26 +0200 Subject: [PATCH 14/46] dummy commit to test --- .../roc_netio/target_berkley/roc_netio/socket_ops.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 0421e70b8..8118ccd35 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -6,6 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +// dummy comment + #include #include From b637adf1b5394c7648ccd5cdc9a3bce72a007ebb Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Wed, 18 Jun 2025 19:35:50 +0200 Subject: [PATCH 15/46] socket_addr.h: remove splitter comments introduced in ad58a97c807e042b4734837951e348c414ef1492 --- .../roc_address/target_berkley/roc_address/socket_addr.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index 77401270c..3066772d2 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -12,7 +12,6 @@ #ifndef ROC_ADDRESS_SOCKET_ADDR_H_ #define ROC_ADDRESS_SOCKET_ADDR_H_ -// splitter comment for clang-format #ifndef __WIN32__ #include #include @@ -23,7 +22,6 @@ typedef uint16_t in_port_t; #include #include #endif // __WIN32__ -// splitter comment for clang-format #include "roc_address/addr_family.h" #include "roc_core/attributes.h" From e96514b1855d0aa500e619d1992a520c6a162dbd Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Wed, 18 Jun 2025 20:13:37 +0200 Subject: [PATCH 16/46] MinGW build without -fpermissive : change some console outputs to %llu --- .../target_libuv/roc_netio/tcp_connection_port.cpp | 2 +- .../target_libuv/roc_netio/tcp_server_port.cpp | 2 +- src/internal_modules/roc_node/receiver_decoder.cpp | 4 ++-- src/internal_modules/roc_node/sender_encoder.cpp | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_connection_port.cpp b/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_connection_port.cpp index 4f3a1c101..95097e7b9 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_connection_port.cpp +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_connection_port.cpp @@ -804,7 +804,7 @@ void TcpConnectionPort::format_descriptor(core::StringBuilder& b) { } b.append_str(" 0x"); - b.append_uint((unsigned long)this, 16); + b.append_uint((size_t)this, 16); b.append_str(" local="); b.append_str(address::socket_addr_to_str(local_address_).c_str()); diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_server_port.cpp b/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_server_port.cpp index 58147844c..9df574f41 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_server_port.cpp +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/tcp_server_port.cpp @@ -325,7 +325,7 @@ void TcpServerPort::format_descriptor(core::StringBuilder& b) { b.append_str("buffer().size()); + " provided=%llu needed=%llu", + (unsigned long long)n_bytes, (unsigned long long)packet->buffer().size()); return status::StatusBadBuffer; } diff --git a/src/internal_modules/roc_node/sender_encoder.cpp b/src/internal_modules/roc_node/sender_encoder.cpp index 624cec50e..391c79567 100644 --- a/src/internal_modules/roc_node/sender_encoder.cpp +++ b/src/internal_modules/roc_node/sender_encoder.cpp @@ -205,8 +205,8 @@ SenderEncoder::read_packet(address::Interface iface, void* bytes, size_t* n_byte roc_log(LogError, "sender encoder node:" " not enough space in provided packet:" - " provided=%lu needed=%lu", - (unsigned long)n_bytes, (unsigned long)packet->buffer().size()); + " provided=%llu needed=%llu", + (unsigned long long)n_bytes, (unsigned long long)packet->buffer().size()); return status::StatusBadBuffer; } @@ -230,9 +230,9 @@ SenderEncoder::write_packet(address::Interface iface, const void* bytes, size_t roc_log(LogError, "sender encoder node:" " provided packet exceeds maximum packet size (see roc_context_config):" - " provided=%lu maximum=%lu", - (unsigned long)n_bytes, - (unsigned long)packet_factory_.packet_buffer_size()); + " provided=%llu maximum=%llu", + (unsigned long long)n_bytes, + (unsigned long long)packet_factory_.packet_buffer_size()); return status::StatusBadBuffer; } From 86fcc6de35db64522daeb6dd83fb6856df996a13 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Wed, 18 Jun 2025 20:59:25 +0200 Subject: [PATCH 17/46] MinGW build without -fpermissive : cast size_t for payload alignment checks --- src/internal_modules/roc_fec/composer.h | 2 +- src/internal_modules/roc_rtcp/composer.cpp | 2 +- src/internal_modules/roc_rtp/composer.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/internal_modules/roc_fec/composer.h b/src/internal_modules/roc_fec/composer.h index 753def05d..6d37f21f2 100644 --- a/src/internal_modules/roc_fec/composer.h +++ b/src/internal_modules/roc_fec/composer.h @@ -43,7 +43,7 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { //! Adjust buffer to align payload. ROC_NODISCARD virtual status::StatusCode align(core::Slice& buffer, size_t header_size, size_t payload_alignment) { - if ((unsigned long)buffer.data() % payload_alignment != 0) { + if ((size_t)buffer.data() % payload_alignment != 0) { roc_panic("fec composer: unexpected non-aligned buffer"); } diff --git a/src/internal_modules/roc_rtcp/composer.cpp b/src/internal_modules/roc_rtcp/composer.cpp index 951913cbb..5858afb92 100644 --- a/src/internal_modules/roc_rtcp/composer.cpp +++ b/src/internal_modules/roc_rtcp/composer.cpp @@ -25,7 +25,7 @@ ROC_NODISCARD status::StatusCode Composer::init_status() const { ROC_NODISCARD status::StatusCode Composer::align(core::Slice& buffer, size_t header_size, size_t payload_alignment) { - if ((unsigned long)buffer.data() % payload_alignment != 0) { + if ((size_t)buffer.data() % payload_alignment != 0) { roc_panic("rtcp composer: unexpected non-aligned buffer"); } diff --git a/src/internal_modules/roc_rtp/composer.cpp b/src/internal_modules/roc_rtp/composer.cpp index 017ff2060..cceabde08 100644 --- a/src/internal_modules/roc_rtp/composer.cpp +++ b/src/internal_modules/roc_rtp/composer.cpp @@ -27,7 +27,7 @@ ROC_NODISCARD status::StatusCode Composer::init_status() const { ROC_NODISCARD status::StatusCode Composer::align(core::Slice& buffer, size_t header_size, size_t payload_alignment) { - if ((unsigned long)buffer.data() % payload_alignment != 0) { + if ((size_t)buffer.data() % payload_alignment != 0) { roc_panic("rtp composer: unexpected non-aligned buffer"); } From 69c639e7a936504a6785fe669ab580eaa9f1f598 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Wed, 18 Jun 2025 21:22:37 +0200 Subject: [PATCH 18/46] MinGW build without -fpermissive : UDP: retrieve libuv's socket handle instead of file descriptor --- .../roc_netio/target_libuv/roc_netio/udp_port.cpp | 7 ++++++- .../roc_netio/target_libuv/roc_netio/udp_port.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp b/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp index ed60a276c..2cf871737 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp @@ -116,11 +116,16 @@ bool UdpPort::open() { return false; } +#ifndef __WIN32__ const int fd_err = uv_fileno((uv_handle_t*)&handle_, &fd_); + if (fd_err != 0) { roc_panic("udp port: %s: uv_fileno(): [%s] %s", descriptor(), uv_err_name(fd_err), uv_strerror(fd_err)); } +#else // __WIN32__ + fd_ = handle_.socket; +#endif // __WIN32__ update_descriptor(); @@ -580,7 +585,7 @@ void UdpPort::format_descriptor(core::StringBuilder& b) { b.append_str(" #include -#ifndef __WIN32__ +#ifdef ROC_TARGET_POSIX #include #include #include -#else // __WIN32__ +#else // ! ROC_TARGET_POSIX #include typedef uint16_t sa_family_t; typedef uint16_t in_port_t; #include #include -#endif // ! __WIN32__ +#endif // ROC_TARGET_POSIX #include #include @@ -34,13 +32,13 @@ typedef uint16_t in_port_t; #include "roc_netio/socket_ops.h" // To compile without -fpermissive -#ifndef __WIN32__ +#ifndef ROC_TARGET_WINDOWS typedef void os_buf_t; typedef int os_val_t; -#else // __WIN32__ +#else // ROC_TARGET_WINDOWS typedef char os_buf_t; typedef char os_val_t; -#endif // ! __WIN32__ +#endif // ! ROC_TARGET_WINDOWS namespace roc { namespace netio { @@ -163,7 +161,7 @@ bool set_int_option( // - for performance reasons: without SOCK_CLOEXEC there are two more system calls bool set_cloexec(SocketHandle sock) { -#ifndef __WIN32__ // Probably no equivalent on Windows +#ifndef ROC_TARGET_WINDOWS // Probably no equivalent on Windows int flags; while ((flags = fcntl(sock, F_GETFD)) == -1) { @@ -190,7 +188,7 @@ bool set_cloexec(SocketHandle sock) { } } -#endif // ! __WIN32__ +#endif // ! ROC_TARGET_WINDOWS return true; } @@ -203,7 +201,7 @@ bool set_cloexec(SocketHandle sock) { // Using SOCK_NONBLOCK is preferred because of performance reasons. // Without SOCK_NONBLOCK there are two more system calls. -#ifndef __WIN32__ +#ifndef ROC_TARGET_WINDOWS bool set_nonblock(SocketHandle sock) { int flags; @@ -235,7 +233,7 @@ bool set_nonblock(SocketHandle sock) { return true; } -#else // __WIN32__ +#else // ROC_TARGET_WINDOWS bool set_nonblock(SocketHandle sock) { int res; @@ -248,7 +246,7 @@ bool set_nonblock(SocketHandle sock) { return (res == NO_ERROR); } -#endif // ! __WIN32__ +#endif // ! ROC_TARGET_WINDOWS #endif // !defined(SOCK_NONBLOCK) @@ -476,7 +474,7 @@ bool socket_end_connect(SocketHandle sock) { return true; } -#ifdef __WIN32__ +#ifdef ROC_TARGET_WINDOWS #define MSG_DONTWAIT (0) // Eeek! but ok... #endif @@ -586,7 +584,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { return 0; } -#ifndef __WIN32__ +#ifndef ROC_TARGET_WINDOWS // Block SIGPIPE for this thread. // This works since kernel sends SIGPIPE to the thread that called send(), // not to the whole process. @@ -610,7 +608,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { if ((sigpipe_pending = sigismember(&sig_pending, SIGPIPE)) == -1) { roc_panic("socket: sigismember(): %s", core::errno_to_str().c_str()); } -#endif // !__WIN32__ +#endif // ! ROC_TARGET_WINDOWS ssize_t ret; while ((ret = send(sock, (os_buf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { @@ -623,7 +621,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { const int saved_errno = errno; -#ifndef __WIN32__ +#ifndef ROC_TARGET_WINDOWS // If send() failed with EPIPE, and SIGPIPE was not already pending before calling // send(), then fetch SIGPIPE from pending signal mask. @@ -644,7 +642,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { if (int err = pthread_sigmask(SIG_SETMASK, &sig_restore, NULL)) { roc_panic("socket: pthread_sigmask(): %s", core::errno_to_str(err).c_str()); } -#endif // !__WIN32__ +#endif // ! ROC_TARGET_WINDOWS if (ret < 0 && is_ewouldblock(saved_errno)) { return SockErr_WouldBlock; @@ -704,7 +702,7 @@ ssize_t socket_try_send_to(SocketHandle sock, return ret; } -#ifdef __WIN32__ +#ifdef ROC_TARGET_WINDOWS #define SHUT_RDWR (SD_BOTH) #endif diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h index 9b6d247b3..c52cf04ed 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h @@ -48,14 +48,14 @@ enum SocketError { }; //! Platform-specific socket handle. -#ifndef __WIN32__ +#ifndef ROC_TARGET_WINDOWS typedef int SocketHandle; #else typedef SOCKET SocketHandle; #endif //! Invalid socket handle. -#ifndef __WIN32__ +#ifndef ROC_TARGET_WINDOWS const SocketHandle SocketInvalid = -1; #else const SocketHandle SocketInvalid = INVALID_SOCKET; From b5b843804506ff552a7c0cf18648c64630e95f71 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 26 Jun 2025 16:38:01 +0200 Subject: [PATCH 20/46] os_buf_t and os_val_t: rename to sockbuf_t and sockopt_t + anonymous namespace --- .../target_berkley/roc_netio/socket_ops.cpp | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 16e2dd889..5a618a5f4 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -15,8 +15,10 @@ #include #else // ! ROC_TARGET_POSIX #include -typedef uint16_t sa_family_t; -typedef uint16_t in_port_t; +namespace { + typedef uint16_t sa_family_t; + typedef uint16_t in_port_t; +} #include #include #endif // ROC_TARGET_POSIX @@ -31,20 +33,20 @@ typedef uint16_t in_port_t; #include "roc_core/panic.h" #include "roc_netio/socket_ops.h" -// To compile without -fpermissive -#ifndef ROC_TARGET_WINDOWS -typedef void os_buf_t; -typedef int os_val_t; -#else // ROC_TARGET_WINDOWS -typedef char os_buf_t; -typedef char os_val_t; -#endif // ! ROC_TARGET_WINDOWS - namespace roc { namespace netio { namespace { +// To compile without -fpermissive +#ifndef ROC_TARGET_WINDOWS +typedef void sockbuf_t; +typedef int sockopt_t; +#else // ROC_TARGET_WINDOWS +typedef char sockbuf_t; +typedef char sockopt_t; +#endif // ! ROC_TARGET_WINDOWS + int to_domain(address::AddrFamily family) { switch (family) { case address::Family_IPv4: @@ -117,7 +119,7 @@ bool get_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int& opt_val) { socklen_t opt_len = sizeof(opt_val); - if (getsockopt(sock, level, opt, (os_val_t*)&opt_val, &opt_len) == -1) { + if (getsockopt(sock, level, opt, (sockopt_t*)&opt_val, &opt_len) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: getsockopt(%s): %s", opt_name, @@ -137,7 +139,7 @@ bool get_int_option( bool set_int_option( SocketHandle sock, int level, int opt, const char* opt_name, int opt_val) { - if (setsockopt(sock, level, opt, (const os_val_t*)&opt_val, sizeof(opt_val)) == -1) { + if (setsockopt(sock, level, opt, (const sockopt_t*)&opt_val, sizeof(opt_val)) == -1) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: setsockopt(%s): %s", opt_name, @@ -487,7 +489,7 @@ ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { } ssize_t ret; - while ((ret = recv(sock, (os_buf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { + while ((ret = recv(sock, (sockbuf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -536,7 +538,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { #endif ssize_t ret; - while ((ret = send(sock, (const os_buf_t*)buf, bufsz, flags)) == -1) { + while ((ret = send(sock, (const sockbuf_t*)buf, bufsz, flags)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -611,7 +613,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { #endif // ! ROC_TARGET_WINDOWS ssize_t ret; - while ((ret = send(sock, (os_buf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { + while ((ret = send(sock, (sockbuf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -672,7 +674,7 @@ ssize_t socket_try_send_to(SocketHandle sock, roc_panic_if(!remote_address.has_host_port()); ssize_t ret; - while ((ret = sendto(sock, (const os_buf_t*)buf, bufsz, MSG_DONTWAIT, + while ((ret = sendto(sock, (const sockbuf_t*)buf, bufsz, MSG_DONTWAIT, remote_address.saddr(), remote_address.slen())) == -1) { roc_panic_if(is_malformed(errno)); @@ -758,7 +760,7 @@ bool socket_close_with_reset(SocketHandle sock) { ling.l_linger = 0; bool setsockopt_failed = false; - if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (const os_val_t*)&ling, sizeof(ling)) + if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (const sockopt_t*)&ling, sizeof(ling)) == -1) { roc_panic_if(is_malformed(errno)); From a51d182da55c26e5e6a6e598de57348006e7dafe Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 26 Jun 2025 18:46:01 +0200 Subject: [PATCH 21/46] ifdefs reorganization in socket_ops.cpp --- .../target_berkley/roc_netio/socket_ops.cpp | 91 ++++++++++++------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 5a618a5f4..0ba2b0070 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -16,9 +16,9 @@ #else // ! ROC_TARGET_POSIX #include namespace { - typedef uint16_t sa_family_t; - typedef uint16_t in_port_t; -} +typedef uint16_t sa_family_t; +typedef uint16_t in_port_t; +} // namespace #include #include #endif // ROC_TARGET_POSIX @@ -38,7 +38,6 @@ namespace netio { namespace { -// To compile without -fpermissive #ifndef ROC_TARGET_WINDOWS typedef void sockbuf_t; typedef int sockopt_t; @@ -162,8 +161,9 @@ bool set_int_option( // // - for performance reasons: without SOCK_CLOEXEC there are two more system calls +#if defined(ROC_TARGET_POSIX) && defined(FD_CLOEXEC) + bool set_cloexec(SocketHandle sock) { -#ifndef ROC_TARGET_WINDOWS // Probably no equivalent on Windows int flags; while ((flags = fcntl(sock, F_GETFD)) == -1) { @@ -190,10 +190,17 @@ bool set_cloexec(SocketHandle sock) { } } -#endif // ! ROC_TARGET_WINDOWS return true; } +#else // !defined(ROC_TARGET_POSIX) || !defined(FD_CLOEXEC) + +bool set_cloexec(SocketHandle sock) { + return true; +} + +#endif // defined(ROC_TARGET_POSIX) && defined(FD_CLOEXEC) + #endif // !defined(SOCK_CLOEXEC) #if !defined(SOCK_NONBLOCK) @@ -203,7 +210,7 @@ bool set_cloexec(SocketHandle sock) { // Using SOCK_NONBLOCK is preferred because of performance reasons. // Without SOCK_NONBLOCK there are two more system calls. -#ifndef ROC_TARGET_WINDOWS +#if defined(ROC_TARGET_POSIX) bool set_nonblock(SocketHandle sock) { int flags; @@ -235,26 +242,26 @@ bool set_nonblock(SocketHandle sock) { return true; } -#else // ROC_TARGET_WINDOWS +#elif defined(ROC_TARGET_WINDOWS) bool set_nonblock(SocketHandle sock) { int res; unsigned long mode = 1; // 0 for blocking, nonzero for non blocking res = ioctlsocket(sock, FIONBIO, &mode); - // if (iResult != NO_ERROR) - // printf("ioctlsocket failed with error: %ld\n", iResult); + // if (res == SOCKET_ERROR) + // TODO: WSAGetLastError + roc_log return (res == NO_ERROR); } -#endif // ! ROC_TARGET_WINDOWS +#endif // defined(ROC_TARGET_POSIX) #endif // !defined(SOCK_NONBLOCK) } // namespace -#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#if defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& new_sock) { new_sock = socket(to_domain(family), to_type(type) | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); @@ -269,7 +276,7 @@ bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& ne return true; } -#else // !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK) +#else // !defined(ROC_TARGET_POSIX) || !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK) bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& new_sock) { new_sock = socket(to_domain(family), to_type(type), 0); @@ -294,9 +301,9 @@ bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& ne return true; } -#endif // defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#endif // defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) -#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#if defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) bool socket_accept(SocketHandle sock, SocketHandle& new_sock, @@ -327,7 +334,7 @@ bool socket_accept(SocketHandle sock, return true; } -#else // !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK) +#else // !defined(ROC_TARGET_POSIX) || !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK) bool socket_accept(SocketHandle sock, SocketHandle& new_sock, @@ -365,7 +372,7 @@ bool socket_accept(SocketHandle sock, return true; } -#endif // defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#endif // defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) bool socket_setup(SocketHandle sock, const SocketOpts& options) { roc_panic_if(sock < 0); @@ -476,10 +483,6 @@ bool socket_end_connect(SocketHandle sock) { return true; } -#ifdef ROC_TARGET_WINDOWS -#define MSG_DONTWAIT (0) // Eeek! but ok... -#endif - ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { roc_panic_if(sock < 0); roc_panic_if(!buf); @@ -488,8 +491,13 @@ ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { return 0; } + int flags = 0; +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; +#endif + ssize_t ret; - while ((ret = recv(sock, (sockbuf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { + while ((ret = recv(sock, (sockbuf_t*)buf, bufsz, flags)) == -1) { roc_panic_if(is_malformed(errno)); if (errno != EINTR) { @@ -513,7 +521,8 @@ ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { return ret; } -#if defined(SO_NOSIGPIPE) || defined(MSG_NOSIGNAL) +#if (defined(ROC_TARGET_POSIX) && (defined(SO_NOSIGPIPE) || defined(MSG_NOSIGNAL))) \ + || defined(ROC_TARGET_WINDOWS) // This version is used if either SO_NOSIGPIPE or MSG_NOSIGNAL is available //. @@ -532,7 +541,12 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { return 0; } - int flags = MSG_DONTWAIT; + int flags = 0; + +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; +#endif + #if defined(MSG_NOSIGNAL) flags |= MSG_NOSIGNAL; #endif @@ -563,7 +577,8 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { return ret; } -#else // !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL) +#else // !defined(ROC_TARGET_POSIX) || (!defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL))) + // && !defined(ROC_TARGET_WINDOWS) // This version is used when both SO_NOSIGPIPE and MSG_NOSIGNAL aren't available. // @@ -586,7 +601,6 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { return 0; } -#ifndef ROC_TARGET_WINDOWS // Block SIGPIPE for this thread. // This works since kernel sends SIGPIPE to the thread that called send(), // not to the whole process. @@ -610,7 +624,6 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { if ((sigpipe_pending = sigismember(&sig_pending, SIGPIPE)) == -1) { roc_panic("socket: sigismember(): %s", core::errno_to_str().c_str()); } -#endif // ! ROC_TARGET_WINDOWS ssize_t ret; while ((ret = send(sock, (sockbuf_t*)buf, bufsz, MSG_DONTWAIT)) == -1) { @@ -623,8 +636,6 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { const int saved_errno = errno; -#ifndef ROC_TARGET_WINDOWS - // If send() failed with EPIPE, and SIGPIPE was not already pending before calling // send(), then fetch SIGPIPE from pending signal mask. if (ret == -1 && saved_errno == EPIPE && sigpipe_pending == 0) { @@ -644,7 +655,6 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { if (int err = pthread_sigmask(SIG_SETMASK, &sig_restore, NULL)) { roc_panic("socket: pthread_sigmask(): %s", core::errno_to_str(err).c_str()); } -#endif // ! ROC_TARGET_WINDOWS if (ret < 0 && is_ewouldblock(saved_errno)) { return SockErr_WouldBlock; @@ -663,7 +673,8 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { return ret; } -#endif // defined(SO_NOSIGPIPE) || defined(MSG_NOSIGNAL) +#endif // (defined(ROC_TARGET_POSIX) && (defined(SO_NOSIGPIPE) || defined(MSG_NOSIGNAL))) + // || defined(ROC_TARGET_WINDOWS) ssize_t socket_try_send_to(SocketHandle sock, const void* buf, @@ -673,8 +684,14 @@ ssize_t socket_try_send_to(SocketHandle sock, roc_panic_if(!buf); roc_panic_if(!remote_address.has_host_port()); + int flags = 0; + +#ifdef MSG_DONTWAIT + flags |= MSG_DONTWAIT; +#endif + ssize_t ret; - while ((ret = sendto(sock, (const sockbuf_t*)buf, bufsz, MSG_DONTWAIT, + while ((ret = sendto(sock, (const sockbuf_t*)buf, bufsz, flags, remote_address.saddr(), remote_address.slen())) == -1) { roc_panic_if(is_malformed(errno)); @@ -711,7 +728,15 @@ ssize_t socket_try_send_to(SocketHandle sock, bool socket_shutdown(SocketHandle sock) { roc_panic_if(sock < 0); - if (shutdown(sock, SHUT_RDWR) == -1) { + int flags = 0; + +#ifdef SHUT_RDWR + flags |= SHUT_RDWR; +#else + flags |= SD_BOTH; +#endif + + if (shutdown(sock, flags) == -1) { roc_panic_if(is_malformed(errno)); // shutdown() on macOS may return ENOTCONN if the other side gracefully From 8707a68c020e5bdeb50f99bb303a07bab3b4f2ee Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Thu, 26 Jun 2025 22:05:22 +0200 Subject: [PATCH 22/46] Cleanup of global namespace in socket_addr --- .../roc_address/socket_addr.cpp | 65 ++++++++++++------- .../target_berkley/roc_address/socket_addr.h | 17 ++--- 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp index fc25b0277..61be7bbdf 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp @@ -13,6 +13,35 @@ #include "roc_address/socket_addr.h" #include "roc_core/endian.h" +namespace { + +#ifdef ROC_TARGET_WINDOWS +typedef ADDRESS_FAMILY sa_family_t; +typedef USHORT in_port_t; +#endif + +socklen_t saddr_size(sa_family_t family) { + switch (family) { + case AF_INET: + return sizeof(sockaddr_in); + case AF_INET6: + return sizeof(sockaddr_in6); + default: + return 0; + } +} + +/* friend declaration would still require the return type into the header... +sa_family_t saddr_family(const roc::address::SocketAddr& sa) { + return sa.saddr_.addr4.sin_family; +}*/ + +sa_family_t saddr_family(const roc::address::saddr_t& sa) { + return sa.addr4.sin_family; +} + +} // namespace + namespace roc { namespace address { @@ -25,11 +54,11 @@ void SocketAddr::clear() { } bool SocketAddr::has_host_port() const { - return saddr_family_() == AF_INET || saddr_family_() == AF_INET6; + return saddr_family(saddr_) == AF_INET || saddr_family(saddr_) == AF_INET6; } bool SocketAddr::set_host_port_saddr(const sockaddr* sa) { - const socklen_t sa_size = saddr_size_(sa->sa_family); + const socklen_t sa_size = saddr_size(sa->sa_family); if (sa_size == 0) { return false; } @@ -90,15 +119,15 @@ const sockaddr* SocketAddr::saddr() const { } socklen_t SocketAddr::slen() const { - return saddr_size_(saddr_family_()); + return saddr_size(saddr_family(saddr_)); } socklen_t SocketAddr::max_slen() const { - return saddr_size_(AF_INET6); + return saddr_size(AF_INET6); } AddrFamily SocketAddr::family() const { - switch (saddr_family_()) { + switch (saddr_family(saddr_)) { case AF_INET: return Family_IPv4; case AF_INET6: @@ -109,7 +138,7 @@ AddrFamily SocketAddr::family() const { } int SocketAddr::port() const { - switch (saddr_family_()) { + switch (saddr_family(saddr_)) { case AF_INET: return core::ntoh16u((uint16_t)saddr_.addr4.sin_port); case AF_INET6: @@ -120,7 +149,7 @@ int SocketAddr::port() const { } bool SocketAddr::is_multicast() const { - switch (saddr_family_()) { + switch (saddr_family(saddr_)) { case AF_INET: return IN_MULTICAST(core::ntoh32u(saddr_.addr4.sin_addr.s_addr)); case AF_INET6: @@ -131,7 +160,7 @@ bool SocketAddr::is_multicast() const { } bool SocketAddr::get_host(char* buf, size_t bufsz) const { - switch (saddr_family_()) { + switch (saddr_family(saddr_)) { case AF_INET: if (!inet_ntop(AF_INET, &saddr_.addr4.sin_addr, buf, (socklen_t)bufsz)) { return false; @@ -156,11 +185,12 @@ SocketAddr::operator const struct unspecified_bool *() const { } bool SocketAddr::operator==(const SocketAddr& other) const { - if (saddr_family_() != other.saddr_family_()) { + // if (saddr_family(saddr_) != other.saddr_family(saddr_)) { + if (saddr_family(saddr_) != saddr_family(other.saddr_)) { return false; } - switch (saddr_family_()) { + switch (saddr_family(saddr_)) { case AF_INET: if (saddr_.addr4.sin_addr.s_addr != other.saddr_.addr4.sin_addr.s_addr) { return false; @@ -192,20 +222,11 @@ bool SocketAddr::operator!=(const SocketAddr& other) const { return !(*this == other); } -socklen_t SocketAddr::saddr_size_(sa_family_t family) { - switch (family) { - case AF_INET: - return sizeof(sockaddr_in); - case AF_INET6: - return sizeof(sockaddr_in6); - default: - return 0; - } -} - -sa_family_t SocketAddr::saddr_family_() const { +/* +sa_family_t SocketAddr::saddr_family_(saddr_) const { return saddr_.addr4.sin_family; } +*/ } // namespace address } // namespace roc diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index de394ce87..6c880c8e8 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -16,9 +16,6 @@ #include #include #else // ! ROC_TARGET_POSIX -#include -typedef uint16_t sa_family_t; -typedef uint16_t in_port_t; #include #include #endif // ROC_TARGET_POSIX @@ -30,6 +27,11 @@ typedef uint16_t in_port_t; namespace roc { namespace address { +typedef union { + sockaddr_in addr4; + sockaddr_in6 addr6; +} saddr_t; + //! Socket address. class SocketAddr { public: @@ -90,17 +92,10 @@ class SocketAddr { }; private: - static socklen_t saddr_size_(sa_family_t family); - - sa_family_t saddr_family_() const; - bool set_host_port_ipv4_(const char* ip, int port); bool set_host_port_ipv6_(const char* ip, int port); - union { - sockaddr_in addr4; - sockaddr_in6 addr6; - } saddr_; + saddr_t saddr_; }; } // namespace address From 2d5666d03f7e16cb6bd6bf16bb421322b2cdfa7c Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sat, 28 Jun 2025 18:10:35 +0200 Subject: [PATCH 23/46] socket_ops: use closesocket() on Windows --- .../target_berkley/roc_netio/socket_ops.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 0ba2b0070..d66fa48ea 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -753,6 +753,8 @@ bool socket_shutdown(SocketHandle sock) { return true; } +#ifndef ROC_TARGET_WINDOWS + bool socket_close(SocketHandle sock) { roc_panic_if(sock < 0); @@ -776,6 +778,30 @@ bool socket_close(SocketHandle sock) { return true; } +#else // ROC_TARGET_WINDOWS + +bool socket_close(SocketHandle sock) { + roc_panic_if(sock == SocketInvalid); + + if (closesocket(sock) == SOCKET_ERROR) { + int sock_err = WSAGetLastError(); + if (sock_err == WSAEINTR) { + // Winsock2: WSAEINTR in closesocket() can only happen using WSACancelBlockingCall + // (not anymore supported in Winsock 2.2 we're using so it'd be safe removing this test, + // and have it LogError instead?) + roc_log(LogDebug, + "socket: closesocket(): assuming WSAEINTR does not indicate a failure"); + } else { + roc_log(LogError, "socket: closesocket(): %s", core::errno_to_str(sock_err).c_str()); + return false; + } + } + + return true; +} + +#endif // ROC_TARGET_WINDOWS + bool socket_close_with_reset(SocketHandle sock) { roc_panic_if(sock < 0); From 9a13a5550e90c4d238633efbeb81c96edd8112cd Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sat, 28 Jun 2025 18:21:56 +0200 Subject: [PATCH 24/46] Error handling in Windows set_nonblock --- .../target_berkley/roc_netio/socket_ops.cpp | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index d66fa48ea..2ae641cc8 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -245,12 +245,14 @@ bool set_nonblock(SocketHandle sock) { #elif defined(ROC_TARGET_WINDOWS) bool set_nonblock(SocketHandle sock) { - int res; unsigned long mode = 1; // 0 for blocking, nonzero for non blocking - res = ioctlsocket(sock, FIONBIO, &mode); - // if (res == SOCKET_ERROR) - // TODO: WSAGetLastError + roc_log + int res = ioctlsocket(sock, FIONBIO, &mode); + if (res == SOCKET_ERROR) { + roc_log(LogError, "socket: ioctlsocket(FIONBIO): %s", + core::errno_to_str(WSAGetLastError()).c_str()); + return false; + } return (res == NO_ERROR); } @@ -784,22 +786,25 @@ bool socket_close(SocketHandle sock) { roc_panic_if(sock == SocketInvalid); if (closesocket(sock) == SOCKET_ERROR) { - int sock_err = WSAGetLastError(); - if (sock_err == WSAEINTR) { - // Winsock2: WSAEINTR in closesocket() can only happen using WSACancelBlockingCall - // (not anymore supported in Winsock 2.2 we're using so it'd be safe removing this test, - // and have it LogError instead?) - roc_log(LogDebug, - "socket: closesocket(): assuming WSAEINTR does not indicate a failure"); - } else { - roc_log(LogError, "socket: closesocket(): %s", core::errno_to_str(sock_err).c_str()); - return false; - } + int sock_err = WSAGetLastError(); + if (sock_err == WSAEINTR) { + // Winsock2: WSAEINTR in closesocket() can only happen using + // WSACancelBlockingCall + // (not anymore supported in Winsock 2.2 we're using so it'd be safe removing + // this test, and have it LogError instead?) + roc_log( + LogDebug, + "socket: closesocket(): assuming WSAEINTR does not indicate a failure"); + } else { + roc_log(LogError, "socket: closesocket(): %s", + core::errno_to_str(sock_err).c_str()); + return false; + } } return true; } - + #endif // ROC_TARGET_WINDOWS bool socket_close_with_reset(SocketHandle sock) { From e328e3e83099ee3b98c6779b5d6b2fa77723d3e0 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sat, 28 Jun 2025 18:44:53 +0200 Subject: [PATCH 25/46] Cond: use errno_to_str in roc_panic --- .../roc_core/target_windows/roc_core/cond.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp b/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp index 0e1e15f78..2b43dcb7c 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp +++ b/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp @@ -7,6 +7,7 @@ */ #include "roc_core/cond.h" +#include "roc_core/errno_to_str.h" #include "roc_core/panic.h" namespace roc { @@ -34,7 +35,8 @@ bool Cond::timed_wait(nanoseconds_t timeout) const { if (err == ERROR_TIMEOUT || err == WAIT_TIMEOUT) { return false; } - roc_panic("cond: SleepConditionVariableCS(): error %lu", err); + roc_panic("cond: SleepConditionVariableCS(): %s", + core::errno_to_str(err).c_str()); } return true; @@ -42,8 +44,7 @@ bool Cond::timed_wait(nanoseconds_t timeout) const { void Cond::wait() const { if (!SleepConditionVariableCS(&cond_, &mutex_, INFINITE)) { - DWORD error = GetLastError(); - roc_panic("cond: SleepConditionVariableCS(): error %lu", error); + roc_panic("cond: SleepConditionVariableCS(): %s", core::errno_to_str().c_str()); } } From d3215a19ccf80737eae6802c00fc35dc5ed67c4e Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 29 Jun 2025 03:07:27 +0200 Subject: [PATCH 26/46] socket_addr: Remove typedef saddr_t for previous saddr_family() --- .../roc_address/socket_addr.cpp | 33 +++++++------------ .../target_berkley/roc_address/socket_addr.h | 10 +++--- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp index 61be7bbdf..0612dffda 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp @@ -31,13 +31,8 @@ socklen_t saddr_size(sa_family_t family) { } } -/* friend declaration would still require the return type into the header... -sa_family_t saddr_family(const roc::address::SocketAddr& sa) { - return sa.saddr_.addr4.sin_family; -}*/ - -sa_family_t saddr_family(const roc::address::saddr_t& sa) { - return sa.addr4.sin_family; +sa_family_t saddr_family(const sockaddr_in& sa4) { + return sa4.sin_family; } } // namespace @@ -54,7 +49,8 @@ void SocketAddr::clear() { } bool SocketAddr::has_host_port() const { - return saddr_family(saddr_) == AF_INET || saddr_family(saddr_) == AF_INET6; + return saddr_family(saddr_.addr4) == AF_INET + || saddr_family(saddr_.addr4) == AF_INET6; } bool SocketAddr::set_host_port_saddr(const sockaddr* sa) { @@ -119,7 +115,7 @@ const sockaddr* SocketAddr::saddr() const { } socklen_t SocketAddr::slen() const { - return saddr_size(saddr_family(saddr_)); + return saddr_size(saddr_family(saddr_.addr4)); } socklen_t SocketAddr::max_slen() const { @@ -127,7 +123,7 @@ socklen_t SocketAddr::max_slen() const { } AddrFamily SocketAddr::family() const { - switch (saddr_family(saddr_)) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: return Family_IPv4; case AF_INET6: @@ -138,7 +134,7 @@ AddrFamily SocketAddr::family() const { } int SocketAddr::port() const { - switch (saddr_family(saddr_)) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: return core::ntoh16u((uint16_t)saddr_.addr4.sin_port); case AF_INET6: @@ -149,7 +145,7 @@ int SocketAddr::port() const { } bool SocketAddr::is_multicast() const { - switch (saddr_family(saddr_)) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: return IN_MULTICAST(core::ntoh32u(saddr_.addr4.sin_addr.s_addr)); case AF_INET6: @@ -160,7 +156,7 @@ bool SocketAddr::is_multicast() const { } bool SocketAddr::get_host(char* buf, size_t bufsz) const { - switch (saddr_family(saddr_)) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: if (!inet_ntop(AF_INET, &saddr_.addr4.sin_addr, buf, (socklen_t)bufsz)) { return false; @@ -185,12 +181,11 @@ SocketAddr::operator const struct unspecified_bool *() const { } bool SocketAddr::operator==(const SocketAddr& other) const { - // if (saddr_family(saddr_) != other.saddr_family(saddr_)) { - if (saddr_family(saddr_) != saddr_family(other.saddr_)) { + if (saddr_family(saddr_.addr4) != saddr_family(other.saddr_.addr4)) { return false; } - switch (saddr_family(saddr_)) { + switch (saddr_family(saddr_.addr4)) { case AF_INET: if (saddr_.addr4.sin_addr.s_addr != other.saddr_.addr4.sin_addr.s_addr) { return false; @@ -222,11 +217,5 @@ bool SocketAddr::operator!=(const SocketAddr& other) const { return !(*this == other); } -/* -sa_family_t SocketAddr::saddr_family_(saddr_) const { - return saddr_.addr4.sin_family; -} -*/ - } // namespace address } // namespace roc diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h index 6c880c8e8..7de9654af 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.h @@ -27,11 +27,6 @@ namespace roc { namespace address { -typedef union { - sockaddr_in addr4; - sockaddr_in6 addr6; -} saddr_t; - //! Socket address. class SocketAddr { public: @@ -95,7 +90,10 @@ class SocketAddr { bool set_host_port_ipv4_(const char* ip, int port); bool set_host_port_ipv6_(const char* ip, int port); - saddr_t saddr_; + union { + sockaddr_in addr4; + sockaddr_in6 addr6; + } saddr_; }; } // namespace address From 4a3c406517c9c62475d9dabc91f87a247a149add Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 29 Jun 2025 14:15:11 +0200 Subject: [PATCH 27/46] socket_ops: move typedefs and replace uint16_t by Winsock types --- .../roc_netio/target_berkley/roc_netio/socket_ops.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 2ae641cc8..e84edcf1a 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -14,11 +14,6 @@ #include #include #else // ! ROC_TARGET_POSIX -#include -namespace { -typedef uint16_t sa_family_t; -typedef uint16_t in_port_t; -} // namespace #include #include #endif // ROC_TARGET_POSIX @@ -44,6 +39,8 @@ typedef int sockopt_t; #else // ROC_TARGET_WINDOWS typedef char sockbuf_t; typedef char sockopt_t; +typedef ADDRESS_FAMILY sa_family_t; +typedef USHORT in_port_t; #endif // ! ROC_TARGET_WINDOWS int to_domain(address::AddrFamily family) { From 8238ac25d0c7865fbf01fa53c20ee309a033fb20 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 29 Jun 2025 14:24:36 +0200 Subject: [PATCH 28/46] socket_ops / winsock: remove WSAEINTR check in socket_close() --- .../target_berkley/roc_netio/socket_ops.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index e84edcf1a..a1b5abb4e 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -783,20 +783,9 @@ bool socket_close(SocketHandle sock) { roc_panic_if(sock == SocketInvalid); if (closesocket(sock) == SOCKET_ERROR) { - int sock_err = WSAGetLastError(); - if (sock_err == WSAEINTR) { - // Winsock2: WSAEINTR in closesocket() can only happen using - // WSACancelBlockingCall - // (not anymore supported in Winsock 2.2 we're using so it'd be safe removing - // this test, and have it LogError instead?) - roc_log( - LogDebug, - "socket: closesocket(): assuming WSAEINTR does not indicate a failure"); - } else { - roc_log(LogError, "socket: closesocket(): %s", - core::errno_to_str(sock_err).c_str()); - return false; - } + roc_log(LogError, "socket: closesocket(): %s", + core::errno_to_str(WSAGetLastError()).c_str()); + return false; } return true; From 521b48ab7c26aa9450badf5b229b2aa12e252765 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 29 Jun 2025 14:51:28 +0200 Subject: [PATCH 29/46] socket_ops: add valid_socket() function and use in roc_panic_if's --- .../target_berkley/roc_netio/socket_ops.cpp | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index a1b5abb4e..41c1ad91f 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -92,6 +92,20 @@ bool is_malformed(int err) { return err == EBADF || err == EFAULT || err == ENOTSOCK; } +#ifndef ROC_TARGET_WINDOWS + +bool valid_socket(SocketHandle sock) { + return sock >= 0; +} + +#else + +bool valid_socket(SocketHandle sock) { + return sock != SocketInvalid; +} + +#endif + bool get_local_address(SocketHandle sock, address::SocketAddr& address) { socklen_t addrlen = address.max_slen(); @@ -307,7 +321,7 @@ bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& ne bool socket_accept(SocketHandle sock, SocketHandle& new_sock, address::SocketAddr& remote_address) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); socklen_t addrlen = remote_address.max_slen(); @@ -338,7 +352,7 @@ bool socket_accept(SocketHandle sock, bool socket_accept(SocketHandle sock, SocketHandle& new_sock, address::SocketAddr& remote_address) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); socklen_t addrlen = remote_address.max_slen(); @@ -374,7 +388,7 @@ bool socket_accept(SocketHandle sock, #endif // defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) bool socket_setup(SocketHandle sock, const SocketOpts& options) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); // If SO_NOSIGPIPE is available, enable it here for socket_try_send(). #if defined(SO_NOSIGPIPE) @@ -392,7 +406,7 @@ bool socket_setup(SocketHandle sock, const SocketOpts& options) { } bool socket_bind(SocketHandle sock, address::SocketAddr& local_address) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!local_address.has_host_port()); // If IPV6_V6ONLY is available, use it for IPv6 addresses. @@ -420,7 +434,7 @@ bool socket_bind(SocketHandle sock, address::SocketAddr& local_address) { } bool socket_listen(SocketHandle sock, size_t backlog) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); if (listen(sock, (int)backlog) == -1) { roc_panic_if(is_malformed(errno)); @@ -435,7 +449,7 @@ bool socket_listen(SocketHandle sock, size_t backlog) { bool socket_begin_connect(SocketHandle sock, const address::SocketAddr& remote_address, bool& completed_immediately) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!remote_address.has_host_port()); int saved_errno = errno; @@ -463,7 +477,7 @@ bool socket_begin_connect(SocketHandle sock, } bool socket_end_connect(SocketHandle sock) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); int err = 0; @@ -483,7 +497,7 @@ bool socket_end_connect(SocketHandle sock) { } ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!buf); if (bufsz == 0) { @@ -533,7 +547,7 @@ ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz) { // // If MSG_NOSIGNAL is available (e.g. on Linux), we pass it to send(). ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!buf); if (bufsz == 0) { @@ -593,7 +607,7 @@ ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { // // This implementation requires POSIX 2001. ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!buf); if (bufsz == 0) { @@ -679,7 +693,7 @@ ssize_t socket_try_send_to(SocketHandle sock, const void* buf, size_t bufsz, const address::SocketAddr& remote_address) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); roc_panic_if(!buf); roc_panic_if(!remote_address.has_host_port()); @@ -725,7 +739,7 @@ ssize_t socket_try_send_to(SocketHandle sock, #endif bool socket_shutdown(SocketHandle sock) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); int flags = 0; @@ -755,7 +769,7 @@ bool socket_shutdown(SocketHandle sock) { #ifndef ROC_TARGET_WINDOWS bool socket_close(SocketHandle sock) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); if (close(sock) == -1) { roc_panic_if(is_malformed(errno)); @@ -794,7 +808,7 @@ bool socket_close(SocketHandle sock) { #endif // ROC_TARGET_WINDOWS bool socket_close_with_reset(SocketHandle sock) { - roc_panic_if(sock < 0); + roc_panic_if(!valid_socket(sock)); // SO_LINGER with zero timeout instructs close() to send RST instead of FIN. struct linger ling; From f2e20fe11fa650574bfd23e7c6b0b42f9c658d67 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Mon, 30 Jun 2025 01:15:08 +0200 Subject: [PATCH 30/46] udp_port: use SocketHandle type for getting uv_fileno() socket handle --- .../roc_netio/target_libuv/roc_netio/udp_port.cpp | 13 ++++++------- .../roc_netio/target_libuv/roc_netio/udp_port.h | 3 ++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp b/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp index 2cf871737..c90ed6c8c 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp @@ -40,7 +40,7 @@ UdpPort::UdpPort(const UdpConfig& config, , recv_started_(false) , want_close_(false) , closed_(false) - , fd_() + , sock_() , packet_factory_(packet_factory) , inbound_writer_(NULL) , rate_limiter_(PacketLogInterval, 1) { @@ -116,16 +116,15 @@ bool UdpPort::open() { return false; } -#ifndef __WIN32__ - const int fd_err = uv_fileno((uv_handle_t*)&handle_, &fd_); + uv_os_fd_t tmpfd; + + const int fd_err = uv_fileno((uv_handle_t*)&handle_, &tmpfd); if (fd_err != 0) { roc_panic("udp port: %s: uv_fileno(): [%s] %s", descriptor(), uv_err_name(fd_err), uv_strerror(fd_err)); } -#else // __WIN32__ - fd_ = handle_.socket; -#endif // __WIN32__ + sock_ = (long long unsigned int)tmpfd; update_descriptor(); @@ -469,7 +468,7 @@ bool UdpPort::try_nonblocking_write_(const packet::PacketPtr& pp) { const packet::UDP& udp = *pp->udp(); const bool success = - socket_try_send_to(fd_, pp->buffer().data(), pp->buffer().size(), udp.dst_addr); + socket_try_send_to(sock_, pp->buffer().data(), pp->buffer().size(), udp.dst_addr); if (success) { const int packet_num = ++sent_packets_; diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.h b/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.h index 3ec013b93..3330f66d0 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.h +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.h @@ -22,6 +22,7 @@ #include "roc_core/rate_limiter.h" #include "roc_netio/basic_port.h" #include "roc_netio/iclose_handler.h" +#include "roc_netio/socket_ops.h" #include "roc_packet/iwriter.h" #include "roc_packet/packet_factory.h" @@ -147,7 +148,7 @@ class UdpPort : public BasicPort, private packet::IWriter { bool want_close_; bool closed_; - uv_os_sock_t fd_; + SocketHandle sock_; packet::PacketFactory& packet_factory_; From cbaa85a7140fed6cdd33980addb8b34559e6292f Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 6 Jul 2025 19:15:11 +0200 Subject: [PATCH 31/46] socket_init/deinit in node context ctor/dtor --- .../target_berkley/roc_netio/socket_ops.cpp | 38 +++++++++++++++++++ .../target_berkley/roc_netio/socket_ops.h | 6 +++ src/internal_modules/roc_node/context.cpp | 9 +++++ 3 files changed, 53 insertions(+) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 41c1ad91f..2ffc86c2b 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -274,6 +274,44 @@ bool set_nonblock(SocketHandle sock) { } // namespace +#ifdef ROC_TARGET_WINDOWS + +bool socket_init() { + WSADATA wsaData; + int err = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (err) { + roc_log(LogError, "WSAStartup: %s", core::errno_to_str(err).c_str()); + return false; + } + return true; +} + +bool socket_deinit() { + int res = WSACleanup(); + if (res) { + if (res == SOCKET_ERROR) { + roc_log(LogError, "WSACleanup: %s", + core::errno_to_str(WSAGetLastError()).c_str()); + } else { + roc_log(LogError, "WSACleanup: returned unexpected value %d", res); + } + return false; + } + return true; +} + +#else // !ROC_TARTGET_WINDOWS + +bool socket_init() { + return true; +} + +bool socket_deinit() { + return true; +} + +#endif // ROC_TARGET_WINDOWS + #if defined(ROC_TARGET_POSIX) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& new_sock) { diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h index c52cf04ed..50c7ce982 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.h @@ -61,6 +61,12 @@ const SocketHandle SocketInvalid = -1; const SocketHandle SocketInvalid = INVALID_SOCKET; #endif +//! Initialize environment for socket functions. +ROC_NODISCARD bool socket_init(); + +//! Cleans socket functions environment. +ROC_NODISCARD bool socket_deinit(); + //! Create non-blocking socket. ROC_NODISCARD bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& new_sock); diff --git a/src/internal_modules/roc_node/context.cpp b/src/internal_modules/roc_node/context.cpp index 7e5b5f74c..3de72f4d8 100644 --- a/src/internal_modules/roc_node/context.cpp +++ b/src/internal_modules/roc_node/context.cpp @@ -28,6 +28,11 @@ Context::Context(const ContextConfig& config, core::IArena& arena) , init_status_(status::NoStatus) { roc_log(LogDebug, "context: initializing"); + if (!roc::netio::socket_init()) { + roc_log(LogError, "context: couldn't initialize sockets"); + return; + } + if ((init_status_ = network_loop_.init_status()) != status::StatusOK) { roc_log(LogError, "context: can't create network loop: status=%s", status::code_to_str(init_status_)); @@ -45,6 +50,10 @@ Context::Context(const ContextConfig& config, core::IArena& arena) Context::~Context() { roc_log(LogDebug, "context: deinitializing"); + + if (!roc::netio::socket_deinit()) { + roc_log(LogError, "context: couldn't cleanup sockets"); + } } status::StatusCode Context::init_status() const { From 7468fa7c560a1655b0be4cadb73b1107fea56eb0 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 6 Jul 2025 23:15:04 +0200 Subject: [PATCH 32/46] MinGW: Clear some llu to %lu warnings --- src/internal_modules/roc_audio/depacketizer.cpp | 17 +++++++++-------- src/internal_modules/roc_audio/frame.cpp | 2 +- src/internal_modules/roc_core/buffer.cpp | 2 +- src/internal_modules/roc_core/print_memory.cpp | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/internal_modules/roc_audio/depacketizer.cpp b/src/internal_modules/roc_audio/depacketizer.cpp index 39b4cac0c..daa109bbc 100644 --- a/src/internal_modules/roc_audio/depacketizer.cpp +++ b/src/internal_modules/roc_audio/depacketizer.cpp @@ -526,14 +526,15 @@ void Depacketizer::commit_frame_(Frame& frame, && frame_stats.n_missing_samples != 0, "depacketizer: incorrect sample counters"); - roc_log(LogTrace, - "depacketizer: returning frame:" - " stream_ts=%lu n_decoded=%lu n_missing=%lu n_dropped=%lu", - (unsigned long)stream_ts_ - - (frame_stats.n_written_samples / sample_spec_.num_channels()), - (unsigned long)frame_stats.n_decoded_samples / sample_spec_.num_channels(), - (unsigned long)frame_stats.n_missing_samples / sample_spec_.num_channels(), - (unsigned long)frame_stats.n_dropped_packets); + roc_log( + LogTrace, + "depacketizer: returning frame:" + " stream_ts=%lu n_decoded=%lu n_missing=%lu n_dropped=%lu", + (unsigned long)(stream_ts_ + - (frame_stats.n_written_samples / sample_spec_.num_channels())), + (unsigned long)(frame_stats.n_decoded_samples / sample_spec_.num_channels()), + (unsigned long)(frame_stats.n_missing_samples / sample_spec_.num_channels()), + (unsigned long)frame_stats.n_dropped_packets); unsigned flags = 0; if (frame_stats.n_decoded_samples != 0) { diff --git a/src/internal_modules/roc_audio/frame.cpp b/src/internal_modules/roc_audio/frame.cpp index 09ff9463c..8506df7e8 100644 --- a/src/internal_modules/roc_audio/frame.cpp +++ b/src/internal_modules/roc_audio/frame.cpp @@ -91,7 +91,7 @@ void Frame::set_num_raw_samples(size_t n_samples) { roc_panic("frame: frame buffer does not have enough capacity:" " requested=%lu available=%lu", (unsigned long)n_samples, - (unsigned long)buffer_.capacity() / sizeof(sample_t)); + (unsigned long)(buffer_.capacity() / sizeof(sample_t))); } buffer_.reslice(0, n_samples * sizeof(sample_t)); diff --git a/src/internal_modules/roc_core/buffer.cpp b/src/internal_modules/roc_core/buffer.cpp index 07451f013..ed8f26e47 100644 --- a/src/internal_modules/roc_core/buffer.cpp +++ b/src/internal_modules/roc_core/buffer.cpp @@ -18,7 +18,7 @@ Buffer::Buffer(IPool& buffer_pool, size_t buffer_size) roc_panic_if_msg(sizeof(Buffer) + buffer_size != buffer_pool.object_size(), "buffer: attempt to create buffer with wrong size:" " requested=%lu expected=%lu", - (unsigned long)sizeof(Buffer) + buffer_size, + (unsigned long)(sizeof(Buffer) + buffer_size), (unsigned long)buffer_pool.object_size()); new (data_) uint8_t[size_]; diff --git a/src/internal_modules/roc_core/print_memory.cpp b/src/internal_modules/roc_core/print_memory.cpp index 629f0ca9a..4f66fb38d 100644 --- a/src/internal_modules/roc_core/print_memory.cpp +++ b/src/internal_modules/roc_core/print_memory.cpp @@ -176,7 +176,7 @@ void print_memory_slice_t(const T* inner, p.writef("@ slice: type=%s off=%lu size=%lu cap=%lu\n", type_to_str(), (unsigned long)off, (unsigned long)inner_size, - (unsigned long)outer_size - off); + (unsigned long)(outer_size - off)); if (outer) { print_impl_t(p, outer, outer_size, off, off + inner_size); From 91b2e97052b0786ea8b249239b267dacc95c974e Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 22 Jul 2025 15:31:41 +0200 Subject: [PATCH 33/46] Windows errno_to_str: explicit casts to clear warnings --- .../roc_core/target_windows/roc_core/errno_to_str.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp b/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp index 924d626f1..0be4de8b6 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp +++ b/src/internal_modules/roc_core/target_windows/roc_core/errno_to_str.cpp @@ -13,7 +13,7 @@ namespace roc { namespace core { errno_to_str::errno_to_str() { - format_(GetLastError()); + format_((int)GetLastError()); } errno_to_str::errno_to_str(int err) { @@ -25,8 +25,8 @@ void errno_to_str::format_(int err) { size_t size = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), wbuf, - sizeof(wbuf) / sizeof(wchar_t) - 1, nullptr); + nullptr, (DWORD)err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + wbuf, sizeof(wbuf) / sizeof(wchar_t) - 1, nullptr); if (size == 0) { strcpy(buffer_, ""); From ff9b950fd016cf1446dc96fed2e37d60ffa42f8d Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 22 Jul 2025 15:33:06 +0200 Subject: [PATCH 34/46] socket_ops: use SocketInvalid comparison instead of -1 --- .../roc_netio/target_berkley/roc_netio/socket_ops.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 2ffc86c2b..0f99514ca 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -332,7 +332,7 @@ bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& ne bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& new_sock) { new_sock = socket(to_domain(family), to_type(type), 0); - if (new_sock == -1) { + if (new_sock == SocketInvalid) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: socket(): %s", core::errno_to_str().c_str()); @@ -396,7 +396,7 @@ bool socket_accept(SocketHandle sock, new_sock = accept(sock, remote_address.saddr(), &addrlen); - if (new_sock == -1) { + if (new_sock == SocketInvalid) { roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: accept(): %s", core::errno_to_str().c_str()); From 65e8df639f688835290811e0312f1723f86b5c9d Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 22 Jul 2025 15:39:00 +0200 Subject: [PATCH 35/46] Fix returning Sockerr_Failure instead of false in bool function --- .../roc_netio/target_berkley/roc_netio/socket_ops.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp index 0f99514ca..7a4b53bfe 100644 --- a/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp +++ b/src/internal_modules/roc_netio/target_berkley/roc_netio/socket_ops.cpp @@ -258,7 +258,7 @@ bool set_nonblock(SocketHandle sock) { bool set_nonblock(SocketHandle sock) { unsigned long mode = 1; // 0 for blocking, nonzero for non blocking - int res = ioctlsocket(sock, FIONBIO, &mode); + int res = ioctlsocket(sock, (long)FIONBIO, &mode); if (res == SOCKET_ERROR) { roc_log(LogError, "socket: ioctlsocket(FIONBIO): %s", core::errno_to_str(WSAGetLastError()).c_str()); @@ -336,7 +336,7 @@ bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& ne roc_panic_if(is_malformed(errno)); roc_log(LogError, "socket: socket(): %s", core::errno_to_str().c_str()); - return SockErr_Failure; + return false; } if (!set_cloexec(new_sock)) { From 0b65f535e5952f42dadf63e4e2e91000c580a8f7 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 22 Jul 2025 16:26:45 +0200 Subject: [PATCH 36/46] inet_ntop bufsz param: use socklen_t on POSIX, size_t on Windows --- .../target_berkley/roc_address/socket_addr.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp index 0612dffda..e4537f709 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp @@ -18,6 +18,9 @@ namespace { #ifdef ROC_TARGET_WINDOWS typedef ADDRESS_FAMILY sa_family_t; typedef USHORT in_port_t; +typedef size_t ntop_bufsz; +#else +typedef socklen_t ntop_bufsz; #endif socklen_t saddr_size(sa_family_t family) { @@ -32,7 +35,7 @@ socklen_t saddr_size(sa_family_t family) { } sa_family_t saddr_family(const sockaddr_in& sa4) { - return sa4.sin_family; + return (sa_family_t)sa4.sin_family; } } // namespace @@ -158,13 +161,13 @@ bool SocketAddr::is_multicast() const { bool SocketAddr::get_host(char* buf, size_t bufsz) const { switch (saddr_family(saddr_.addr4)) { case AF_INET: - if (!inet_ntop(AF_INET, &saddr_.addr4.sin_addr, buf, (socklen_t)bufsz)) { + if (!inet_ntop(AF_INET, &saddr_.addr4.sin_addr, buf, (ntop_bufsz)bufsz)) { return false; } break; case AF_INET6: - if (!inet_ntop(AF_INET6, &saddr_.addr6.sin6_addr, buf, (socklen_t)bufsz)) { + if (!inet_ntop(AF_INET6, &saddr_.addr6.sin6_addr, buf, (ntop_bufsz)bufsz)) { return false; } break; From 254991cd1e87e1297aa472bfc5e932b9f287e741 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 22 Jul 2025 16:57:07 +0200 Subject: [PATCH 37/46] Windows cond.cpp: explicit cast to clear a sign warning --- src/internal_modules/roc_core/target_windows/roc_core/cond.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp b/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp index 2b43dcb7c..ac8900031 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp +++ b/src/internal_modules/roc_core/target_windows/roc_core/cond.cpp @@ -36,7 +36,7 @@ bool Cond::timed_wait(nanoseconds_t timeout) const { return false; } roc_panic("cond: SleepConditionVariableCS(): %s", - core::errno_to_str(err).c_str()); + core::errno_to_str((int)err).c_str()); } return true; From 5dfa4e6b45d2721aa8ee523a3fac232ef7cd20a6 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sat, 4 Oct 2025 20:46:37 +0200 Subject: [PATCH 38/46] Fix sign-conversion warning on IN_MULTICAST in socket_addr.cpp --- scripts/scons_helpers/build-3rdparty.py | 3 ++- .../target_berkley/roc_address/socket_addr.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/scons_helpers/build-3rdparty.py b/scripts/scons_helpers/build-3rdparty.py index 5ab4a210d..236754a08 100644 --- a/scripts/scons_helpers/build-3rdparty.py +++ b/scripts/scons_helpers/build-3rdparty.py @@ -1221,7 +1221,8 @@ def die(text, *args): setattr(ctx, 'res_dir', 'bin/Release') download( ctx, - 'https://github.com/roc-streaming/openfec/archive/v{ctx.pkg_ver}.tar.gz', + #'https://github.com/roc-streaming/openfec/archive/v{ctx.pkg_ver}.tar.gz', + 'https://www.jmd-tech.com/public/openfec-mgw-v{ctx.pkg_ver}.tar.gz', 'openfec_v{ctx.pkg_ver}.tar.gz') unpack(ctx, 'openfec_v{ctx.pkg_ver}.tar.gz', diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp index e4537f709..b9b18daca 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp @@ -147,10 +147,17 @@ int SocketAddr::port() const { } } +#ifndef ROC_TARGET_WINDOWS +#define IN_MULTICAST_U(i) IN_MULTICAST(i) +#else +// Defined as (((long)(i) & 0xf0000000) == 0xe0000000) in Windows, causes Wsign-conversion +#define IN_MULTICAST_U(i) (((unsigned long)(i) & 0xf0000000u) == 0xe0000000u) +#endif + bool SocketAddr::is_multicast() const { switch (saddr_family(saddr_.addr4)) { case AF_INET: - return IN_MULTICAST(core::ntoh32u(saddr_.addr4.sin_addr.s_addr)); + return IN_MULTICAST_U(core::ntoh32u(saddr_.addr4.sin_addr.s_addr)); case AF_INET6: return IN6_IS_ADDR_MULTICAST(&saddr_.addr6.sin6_addr); default: From 6be6d2b4c2b8e0c6d0db8120655ad708ccdef05c Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sat, 4 Oct 2025 20:48:33 +0200 Subject: [PATCH 39/46] Add time.cpp implementation in target_windows --- .../roc_core/target_windows/roc_core/time.cpp | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/internal_modules/roc_core/target_windows/roc_core/time.cpp diff --git a/src/internal_modules/roc_core/target_windows/roc_core/time.cpp b/src/internal_modules/roc_core/target_windows/roc_core/time.cpp new file mode 100644 index 000000000..80d5c9ed6 --- /dev/null +++ b/src/internal_modules/roc_core/target_windows/roc_core/time.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "roc_core/time.h" +#include "roc_core/errno_to_str.h" +#include "roc_core/panic.h" + +#include + +// Present when compiling with MinGW in Windows, +// but not defined when cross-compiling from Linux (Debian 12) +#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION +#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION (0x00000002) +#endif + +namespace roc { +namespace core { + +namespace { + +#if defined(CLOCK_REALTIME) + +clockid_t map_clock(clock_t clock) { + if (clock == ClockMonotonic) { +#if defined(CLOCK_MONOTONIC) + return CLOCK_MONOTONIC; +#endif + } + + return CLOCK_REALTIME; +} + +#endif + +} // namespace + +nanoseconds_t timestamp(clock_t clock) { + timespec ts; + if (clock_gettime(map_clock(clock), &ts) == -1) { + roc_panic("time: clock_gettime(): %s", errno_to_str().c_str()); + } + + return nanoseconds_t(ts.tv_sec) * 1000000000 + nanoseconds_t(ts.tv_nsec); +} + +void sleep_for(clock_t clock, nanoseconds_t ns) { + // TODO: handle fallback to non high-resolution timer? (waitable high resolution timer + // supported only from W10 1803) + HANDLE hTimer = CreateWaitableTimerEx( + NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS); + if (!hTimer) { + roc_panic("time: CreateWaitableTimerEx(): %s", errno_to_str().c_str()); + } + LARGE_INTEGER dueTime; + dueTime.QuadPart = ns / -100; // In 100 nanoseconds interval, negative = relative + // value. + // should we add -1 to round for "at least" xx ns? + if (!SetWaitableTimer(hTimer, &dueTime, 0 /*once*/, NULL, NULL, FALSE)) { + roc_panic("time: SetWaitableTimer(): %s", errno_to_str().c_str()); + } + if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) { + roc_panic("time: WaitForSingleObject(): %s", errno_to_str().c_str()); + } + CloseHandle(hTimer); +} + +void sleep_until(clock_t clock, nanoseconds_t ns) { + nanoseconds_t now = timestamp(clock); + if (ns > now) { + sleep_for(clock, ns - now); + } +} + +std::tm nanoseconds_2_tm(nanoseconds_t timestamp) { + const time_t sec = time_t(timestamp / Second); + + std::tm tm; + errno_t err = localtime_s(&tm, &sec); + if (err) + roc_panic("time: localtime_s(): %s", errno_to_str(err).c_str()); + + return tm; +} + +nanoseconds_t tm_2_nanoseconds(std::tm tm) { + const time_t sec = mktime(&tm); + + if (sec == (time_t)-1) { + roc_panic("time: mktime(): %s", errno_to_str().c_str()); + } + + return nanoseconds_t(sec) * Second; +} + +} // namespace core +} // namespace roc From 34c4aca9668204c755e0a870afc0a680ddc08af9 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 5 Oct 2025 16:21:11 +0200 Subject: [PATCH 40/46] fix formatting --- .../roc_address/target_berkley/roc_address/socket_addr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp index b9b18daca..baf296b06 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp @@ -148,10 +148,10 @@ int SocketAddr::port() const { } #ifndef ROC_TARGET_WINDOWS -#define IN_MULTICAST_U(i) IN_MULTICAST(i) +#define IN_MULTICAST_U(i) IN_MULTICAST(i) #else // Defined as (((long)(i) & 0xf0000000) == 0xe0000000) in Windows, causes Wsign-conversion -#define IN_MULTICAST_U(i) (((unsigned long)(i) & 0xf0000000u) == 0xe0000000u) +#define IN_MULTICAST_U(i) (((unsigned long)(i)&0xf0000000u) == 0xe0000000u) #endif bool SocketAddr::is_multicast() const { From 6078d1c21a59ccf8dfe807864f48e28aab8e0de0 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Sun, 5 Oct 2025 20:56:50 +0200 Subject: [PATCH 41/46] scons fmt didn't help, trying by disabling clang-format on offending line --- .../roc_address/target_berkley/roc_address/socket_addr.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp index baf296b06..914288726 100644 --- a/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_berkley/roc_address/socket_addr.cpp @@ -151,7 +151,9 @@ int SocketAddr::port() const { #define IN_MULTICAST_U(i) IN_MULTICAST(i) #else // Defined as (((long)(i) & 0xf0000000) == 0xe0000000) in Windows, causes Wsign-conversion -#define IN_MULTICAST_U(i) (((unsigned long)(i)&0xf0000000u) == 0xe0000000u) +// clang-format off +#define IN_MULTICAST_U(i) (((unsigned long)(i) & 0xf0000000u) == 0xe0000000u) +// clang-format on #endif bool SocketAddr::is_multicast() const { From 3a6540eb6450898c9a9e923c37eab9872460ece7 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 2 Jun 2026 14:13:50 +0200 Subject: [PATCH 42/46] No-op crash_handler for target_windows --- .../target_windows/roc_core/crash_handler.h | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/internal_modules/roc_core/target_windows/roc_core/crash_handler.h diff --git a/src/internal_modules/roc_core/target_windows/roc_core/crash_handler.h b/src/internal_modules/roc_core/target_windows/roc_core/crash_handler.h new file mode 100644 index 000000000..6c0d35c6c --- /dev/null +++ b/src/internal_modules/roc_core/target_windows/roc_core/crash_handler.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +//! @file roc_core/target_windows/roc_core/crash_handler.h +//! @brief Crash handling. + +#ifndef ROC_CORE_CRASH_HANDLER_H_ +#define ROC_CORE_CRASH_HANDLER_H_ + +#include "roc_core/noncopyable.h" + +namespace roc { +namespace core { + +//! Crash handler. +class CrashHandler : public core::NonCopyable<> {}; + +} // namespace core +} // namespace roc + +#endif // ROC_CORE_CRASH_HANDLER_H_ From 95901032e4d1372a5ee5b6127ca843728f4391ee Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 2 Jun 2026 22:32:30 +0200 Subject: [PATCH 43/46] Add Windows API semaphore functions --- .../target_windows/roc_core/semaphore.cpp | 83 +++++++++++++++++++ .../target_windows/roc_core/semaphore.h | 54 ++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 src/internal_modules/roc_core/target_windows/roc_core/semaphore.cpp create mode 100644 src/internal_modules/roc_core/target_windows/roc_core/semaphore.h diff --git a/src/internal_modules/roc_core/target_windows/roc_core/semaphore.cpp b/src/internal_modules/roc_core/target_windows/roc_core/semaphore.cpp new file mode 100644 index 000000000..d48c61007 --- /dev/null +++ b/src/internal_modules/roc_core/target_windows/roc_core/semaphore.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "roc_core/semaphore.h" +#include "roc_core/cpu_instructions.h" +#include "roc_core/errno_to_str.h" +#include "roc_core/panic.h" + +#include + +namespace roc { +namespace core { + +Semaphore::Semaphore(unsigned counter) + : guard_(0) { + sem_ = CreateSemaphore(NULL, (LONG)counter, INT_MAX, NULL); + if (!sem_) { + roc_panic("semaphore: CreateSemaphore(): %s", errno_to_str().c_str()); + } +} + +Semaphore::~Semaphore() { + // TODO: faut-il release ici avant le CloseHandle? + while (guard_) { + cpu_relax(); + } + if (!CloseHandle(sem_)) { + roc_panic("semaphore: CloseHandle(): %s", errno_to_str().c_str()); + } +} + +bool Semaphore::timed_wait(nanoseconds_t deadline) { + if (deadline < 0) { + roc_panic("semaphore: unexpected negative deadline"); + } + + DWORD deadline_ms = deadline / 1000000; + if (deadline && !deadline_ms) { + deadline_ms = 1; + } + + DWORD wr = WaitForSingleObject(sem_, deadline_ms); + + switch (wr) { + case WAIT_OBJECT_0: + return true; + case WAIT_TIMEOUT: + return false; + case WAIT_FAILED: + roc_panic("semaphore: WaitForSingleObject(): %s", errno_to_str().c_str()); + default: + roc_panic("semaphore: WaitForSingleObject(): unexpected return %lu", wr); + } +} + +void Semaphore::wait() { + DWORD wr = WaitForSingleObject(sem_, INFINITE); + + switch (wr) { + case WAIT_OBJECT_0: + return; + case WAIT_FAILED: + roc_panic("semaphore: WaitForSingleObject(): %s", errno_to_str().c_str()); + default: + roc_panic("semaphore: WaitForSingleObject(): unexpected return %lu", wr); + } +} + +void Semaphore::post() { + ++guard_; + if (!ReleaseSemaphore(sem_, 1, NULL)) { + roc_panic("semaphore: ReleaseSemaphore(): %s", errno_to_str().c_str()); + } + --guard_; +} + +} // namespace core +} // namespace roc diff --git a/src/internal_modules/roc_core/target_windows/roc_core/semaphore.h b/src/internal_modules/roc_core/target_windows/roc_core/semaphore.h new file mode 100644 index 000000000..9e5f14e0c --- /dev/null +++ b/src/internal_modules/roc_core/target_windows/roc_core/semaphore.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +//! @file roc_core/target_windows/roc_core/semaphore.h +//! @brief Semaphore. + +#ifndef ROC_CORE_SEMAPHORE_H_ +#define ROC_CORE_SEMAPHORE_H_ + +#include "roc_core/atomic_int.h" +#include "roc_core/attributes.h" +#include "roc_core/noncopyable.h" +#include "roc_core/time.h" + +#include + +namespace roc { +namespace core { + +//! Semaphore. +class Semaphore : public NonCopyable<> { +public: + //! Initialize semaphore with given counter. + explicit Semaphore(unsigned counter = 0); + + ~Semaphore(); + + //! Wait until the counter becomes non-zero, decrement it, and return true. + //! If deadline expires before the counter becomes non-zero, returns false. + //! Deadline should be in the same time domain as core::timestamp(). + ROC_NODISCARD bool timed_wait(nanoseconds_t deadline); + + //! Wait until the counter becomes non-zero, decrement it, and return. + void wait(); + + //! Increment counter and wake up blocked waits. + //! This method is lock-free at least on recent glibc and musl versions + //! (which implement POSIX semaphores using a futex and an atomic). + void post(); + +private: + HANDLE sem_; + AtomicInt guard_; +}; + +} // namespace core +} // namespace roc + +#endif // ROC_CORE_SEMAPHORE_H_ From b64ad90ff5d1e3a04eafdcc495ab182df5045644 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 9 Jun 2026 04:08:56 +0200 Subject: [PATCH 44/46] target_windows: use Windows API mutexes in console --- .../target_windows/roc_core/console.cpp | 165 ++++++++++++++++++ .../target_windows/roc_core/console.h | 45 +++++ 2 files changed, 210 insertions(+) create mode 100644 src/internal_modules/roc_core/target_windows/roc_core/console.cpp create mode 100644 src/internal_modules/roc_core/target_windows/roc_core/console.h diff --git a/src/internal_modules/roc_core/target_windows/roc_core/console.cpp b/src/internal_modules/roc_core/target_windows/roc_core/console.cpp new file mode 100644 index 000000000..75c884bc1 --- /dev/null +++ b/src/internal_modules/roc_core/target_windows/roc_core/console.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2019 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "roc_core/console.h" +#include "roc_core/atomic_ops.h" + +#include +#include +#include +#include +#include +#include + +// ANSI Color Codes. +#define COLOR_NONE "" +#define COLOR_START "\033[" +#define COLOR_END "m" +#define COLOR_RESET COLOR_START "0" COLOR_END +#define COLOR_SEPARATOR ";" +#define COLOR_BOLD "1" +#define COLOR_BLACK "30" +#define COLOR_RED "31" +#define COLOR_GREEN "32" +#define COLOR_YELLOW "33" +#define COLOR_BLUE "34" +#define COLOR_MAGENTA "35" +#define COLOR_CYAN "36" +#define COLOR_WHITE "37" + +namespace roc { +namespace core { + +namespace { + +// Serializes console operations. +HANDLE console_mutex = CreateMutex(NULL,FALSE,NULL); + +// -1 means unknown, 0 means no support, +1 means have support. +int console_colors = -1; + +bool env_has_no_color() { + const char* no_color = getenv("NO_COLOR"); + if (no_color) { + return strnlen(no_color, 16) > 0; + } + return false; +} + +bool env_has_force_color() { + const char* force_color = getenv("FORCE_COLOR"); + if (force_color) { + char* end; + long value = strtol(force_color, &end, 10); + if (*force_color != '\0' && *end == '\0') { + return value > 0; + } + } + return false; +} + +bool term_supports_color() { + if (_isatty(STDERR_FILENO)) { + const char* term = getenv("TERM"); + if (term) { + return strncmp("dumb", term, 4) != 0; + } + } + return false; +} + +bool detect_color_support() { + if (env_has_no_color()) { + return false; + } else if (env_has_force_color()) { + return true; + } + return term_supports_color(); +} + +const char* color_code(Color color) { + switch (color) { + case Color_White: + return COLOR_START COLOR_BOLD COLOR_SEPARATOR COLOR_WHITE COLOR_END; + case Color_Gray: + return COLOR_START COLOR_SEPARATOR COLOR_WHITE COLOR_END; + case Color_Red: + return COLOR_START COLOR_BOLD COLOR_SEPARATOR COLOR_RED COLOR_END; + case Color_Green: + return COLOR_START COLOR_BOLD COLOR_SEPARATOR COLOR_GREEN COLOR_END; + case Color_Yellow: + return COLOR_START COLOR_BOLD COLOR_SEPARATOR COLOR_YELLOW COLOR_END; + case Color_Blue: + return COLOR_START COLOR_BOLD COLOR_SEPARATOR COLOR_BLUE COLOR_END; + case Color_Magenta: + return COLOR_START COLOR_BOLD COLOR_SEPARATOR COLOR_MAGENTA COLOR_END; + case Color_Cyan: + return COLOR_START COLOR_BOLD COLOR_SEPARATOR COLOR_CYAN COLOR_END; + default: + break; + } + return COLOR_NONE; +} + +} // namespace + +bool console_supports_colors() { + int colors = AtomicOps::load_seq_cst(console_colors); + + if (colors == -1) { + WaitForSingleObject(console_mutex,INFINITE); + + colors = detect_color_support() ? 1 : 0; + AtomicOps::store_seq_cst(console_colors, colors); + + ReleaseMutex(console_mutex); + } + + return colors; +} + +void console_println(const char* format, ...) { + WaitForSingleObject(console_mutex,INFINITE); + + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + fprintf(stderr, "\n"); + fflush(stderr); + + ReleaseMutex(console_mutex); +} + +void console_println(Color color, const char* format, ...) { + const bool use_colors = (color != Color_None) && console_supports_colors(); + + WaitForSingleObject(console_mutex,INFINITE); + + if (use_colors) { + fprintf(stderr, "%s", color_code(color)); + } + + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + if (use_colors) { + fprintf(stderr, "%s", COLOR_RESET); + } + + fprintf(stderr, "\n"); + fflush(stderr); + + ReleaseMutex(console_mutex); +} + +} // namespace core +} // namespace roc diff --git a/src/internal_modules/roc_core/target_windows/roc_core/console.h b/src/internal_modules/roc_core/target_windows/roc_core/console.h new file mode 100644 index 000000000..18a74110b --- /dev/null +++ b/src/internal_modules/roc_core/target_windows/roc_core/console.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +//! @file roc_core/target_windows/roc_core/console.h +//! @brief Console functions. + +#ifndef ROC_CORE_CONSOLE_H_ +#define ROC_CORE_CONSOLE_H_ + +#include "roc_core/attributes.h" + +namespace roc { +namespace core { + +//! Color ID. +enum Color { + Color_None, + Color_White, + Color_Gray, + Color_Red, + Color_Green, + Color_Yellow, + Color_Blue, + Color_Magenta, + Color_Cyan +}; + +//! Check if colors can be used. +bool console_supports_colors(); + +//! Print line. +ROC_PRINTF(1, 2) void console_println(const char* format, ...); + +//! Print line (with color). +ROC_PRINTF(2, 3) void console_println(Color color, const char* format, ...); + +} // namespace core +} // namespace roc + +#endif // ROC_CORE_CONSOLE_H_ From a25abf8489b6210546ebb515b9c25ce44eeede7f Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 9 Jun 2026 04:11:54 +0200 Subject: [PATCH 45/46] semaphore: comment update --- .../roc_core/target_windows/roc_core/semaphore.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/internal_modules/roc_core/target_windows/roc_core/semaphore.h b/src/internal_modules/roc_core/target_windows/roc_core/semaphore.h index 9e5f14e0c..fa99c8aeb 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/semaphore.h +++ b/src/internal_modules/roc_core/target_windows/roc_core/semaphore.h @@ -39,8 +39,6 @@ class Semaphore : public NonCopyable<> { void wait(); //! Increment counter and wake up blocked waits. - //! This method is lock-free at least on recent glibc and musl versions - //! (which implement POSIX semaphores using a futex and an atomic). void post(); private: From 1c3f8b1713d54f31b9d19ce870007144bd496139 Mon Sep 17 00:00:00 2001 From: Julien Marodon Date: Tue, 9 Jun 2026 04:18:30 +0200 Subject: [PATCH 46/46] scons fmt --- .../roc_core/target_windows/roc_core/console.cpp | 12 ++++++------ src/internal_modules/roc_rtp/headers.h | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/internal_modules/roc_core/target_windows/roc_core/console.cpp b/src/internal_modules/roc_core/target_windows/roc_core/console.cpp index 75c884bc1..7d2daa0c2 100644 --- a/src/internal_modules/roc_core/target_windows/roc_core/console.cpp +++ b/src/internal_modules/roc_core/target_windows/roc_core/console.cpp @@ -9,12 +9,12 @@ #include "roc_core/console.h" #include "roc_core/atomic_ops.h" -#include +#include #include #include #include #include -#include +#include // ANSI Color Codes. #define COLOR_NONE "" @@ -38,7 +38,7 @@ namespace core { namespace { // Serializes console operations. -HANDLE console_mutex = CreateMutex(NULL,FALSE,NULL); +HANDLE console_mutex = CreateMutex(NULL, FALSE, NULL); // -1 means unknown, 0 means no support, +1 means have support. int console_colors = -1; @@ -112,7 +112,7 @@ bool console_supports_colors() { int colors = AtomicOps::load_seq_cst(console_colors); if (colors == -1) { - WaitForSingleObject(console_mutex,INFINITE); + WaitForSingleObject(console_mutex, INFINITE); colors = detect_color_support() ? 1 : 0; AtomicOps::store_seq_cst(console_colors, colors); @@ -124,7 +124,7 @@ bool console_supports_colors() { } void console_println(const char* format, ...) { - WaitForSingleObject(console_mutex,INFINITE); + WaitForSingleObject(console_mutex, INFINITE); va_list args; va_start(args, format); @@ -140,7 +140,7 @@ void console_println(const char* format, ...) { void console_println(Color color, const char* format, ...) { const bool use_colors = (color != Color_None) && console_supports_colors(); - WaitForSingleObject(console_mutex,INFINITE); + WaitForSingleObject(console_mutex, INFINITE); if (use_colors) { fprintf(stderr, "%s", color_code(color)); diff --git a/src/internal_modules/roc_rtp/headers.h b/src/internal_modules/roc_rtp/headers.h index 29fc3e424..bc32e44c6 100644 --- a/src/internal_modules/roc_rtp/headers.h +++ b/src/internal_modules/roc_rtp/headers.h @@ -140,7 +140,7 @@ ROC_PACKED_BEGIN class Header { //! Set version. void set_version(Version v) { roc_panic_if((v & Flag_VersionMask) != v); - flags_ &= (uint8_t) ~(Flag_VersionMask << Flag_VersionShift); + flags_ &= (uint8_t)~(Flag_VersionMask << Flag_VersionShift); flags_ |= ((uint8_t)v << Flag_VersionShift); } @@ -151,7 +151,7 @@ ROC_PACKED_BEGIN class Header { //! Set padding flag. void set_padding(bool v) { - flags_ &= (uint8_t) ~(Flag_PaddingMask << Flag_PaddingShift); + flags_ &= (uint8_t)~(Flag_PaddingMask << Flag_PaddingShift); flags_ |= ((v ? 1 : 0) << Flag_PaddingShift); } @@ -168,7 +168,7 @@ ROC_PACKED_BEGIN class Header { //! Set payload type. void set_payload_type(uint8_t pt) { roc_panic_if((pt & MPT_PayloadTypeMask) != pt); - mpt_ &= (uint8_t) ~(MPT_PayloadTypeMask << MPT_PayloadTypeShift); + mpt_ &= (uint8_t)~(MPT_PayloadTypeMask << MPT_PayloadTypeShift); mpt_ |= (pt << MPT_PayloadTypeShift); } @@ -179,7 +179,7 @@ ROC_PACKED_BEGIN class Header { //! Set marker bit. void set_marker(bool m) { - mpt_ &= (uint8_t) ~(MPT_MarkerMask << MPT_MarkerShift); + mpt_ &= (uint8_t)~(MPT_MarkerMask << MPT_MarkerShift); mpt_ |= ((!!m) << MPT_MarkerShift); }