diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3422b73d1..d69a8d991 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -122,19 +122,24 @@ endforeach()
# SRT_MAVG_SAMPLING_RATE 40 /* Max sampling rate */
# SRT_ENABLE_FREQUENT_LOG_TRACE 0 : set to 1 to enable printing reason for suppressed freq logs
-# CMake offers the OLD behavior, where names that are defined below with
-# option() function, will be deleted if they are not in cache or do not have set
-# type - so effectively options provided through LIBSRT_* prefix would be rejected.
-# We do want these variables, obviously.
-# NOTE: This is introduced in cmake 3.13, so the namespaced-option feature will not
-# work properly in the old cmake.
-if (CMAKE_VERSION VERSION_GREATER 3.12)
- cmake_policy(SET CMP0077 NEW)
-endif()
-
-# Import all options preceded with LIBSRT_ likely from a parent scope.
-# Names are not being checked, at worst it will set an unused variable.
-srt_import_parent_options()
+# Blocked by a general enabler, LIBSRT_ENABLE_IMPORT_VARIABLES, to prevent accidental use.
+if ( (DEFINED LIBSRT_ENABLE_IMPORT_VARIABLES) AND (LIBSRT_ENABLE_IMPORT_VARIABLES EQUAL 1))
+ unset(LIBSRT_ENABLE_IMPORT_VARIABLES)
+
+ # CMake offers sometimes OLD behavior, where names that are defined below with
+ # option() function, will be deleted if they are not in cache or do not have set
+ # type - so effectively options provided through LIBSRT_* prefix would be rejected.
+ # We do want these variables, obviously.
+ # NOTE: This is introduced in cmake 3.13, so the namespaced-option feature will not
+ # work properly in the old cmake.
+ if (CMAKE_VERSION VERSION_GREATER 3.12)
+ cmake_policy(SET CMP0077 NEW)
+ endif()
+
+ # Import all options preceded with LIBSRT_ likely from a parent scope.
+ # Names are not being checked, at worst it will set an unused variable.
+ srt_import_parent_options()
+endif()
# option defaults
set(ENABLE_HEAVY_LOGGING_DEFAULT OFF)
diff --git a/README.md b/README.md
index b0df582af..9d6a6bcc6 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,6 @@
[![License: MPLv2.0][license-badge]](./LICENSE)
[![Latest release][release-badge]][github releases]
[![codecov][codecov-badge]][codecov-project]
-[![Build Status Linux and macOS][travis-badge]][travis]
[![Build Status Windows][appveyor-badge]][appveyor]
[![Ubuntu 24.04][Ubuntu-badge]][Ubuntu-package]
@@ -216,8 +215,6 @@ By contributing code to the SRT project, you agree to license your contribution
[appveyor-badge]: https://img.shields.io/appveyor/ci/Haivision/srt/master.svg?label=Windows
[appveyor]: https://ci.appveyor.com/project/Haivision/srt
-[travis-badge]: https://img.shields.io/travis/Haivision/srt/master.svg?label=Linux/macOS
-[travis]: https://travis-ci.org/Haivision/srt
[license-badge]: https://img.shields.io/badge/License-MPLv2.0-blue
[Vcpkg-package]: https://repology.org/project/srt/versions
@@ -236,10 +233,10 @@ By contributing code to the SRT project, you agree to license your contribution
[debian-package]: https://packages.debian.org/testing/libs/libsrt1.5-gnutls
[fedora-package]: https://repology.org/project/srt/versions
-[fedora-badge]: https://repology.org/badge/version-for-repo/fedora_37/srt.svg
+[fedora-badge]: https://repology.org/badge/version-for-repo/fedora_43/srt.svg
[homebrew-package]: https://repology.org/project/srt/versions
[homebrew-badge]: https://repology.org/badge/version-for-repo/homebrew/srt.svg
[Ubuntu-package]: https://repology.org/project/srt/versions
-[Ubuntu-badge]: https://repology.org/badge/version-for-repo/ubuntu_24_04/srt.svg
+[Ubuntu-badge]: https://repology.org/badge/version-for-repo/ubuntu_26_04/srt.svg
diff --git a/docs/API/API-functions.md b/docs/API/API-functions.md
index 928fd6aaa..fc82776ab 100644
--- a/docs/API/API-functions.md
+++ b/docs/API/API-functions.md
@@ -612,9 +612,10 @@ the listener socket to accept group connections
| [`SRT_EINVPARAM`](#srt_einvparam) | Value of `backlog` is 0 or negative. |
| [`SRT_EINVSOCK`](#srt_einvsock) | Socket [`u`](#u) indicates no valid SRT socket. |
| [`SRT_EUNBOUNDSOCK`](#srt_eunboundsock) | [`srt_bind`](#srt_bind) has not yet been called on that socket. |
+| [`SRT_ESCLOSED`](#srt_esclosed) | The socket has been closed |
| [`SRT_ERDVNOSERV`](#srt_erdvnoserv) | [`SRTO_RENDEZVOUS`](API-socket-options.md#SRTO_RENDEZVOUS) flag is set to true on specified socket. |
| [`SRT_EINVOP`](#srt_einvop) | Internal error (should not happen when [`SRT_EUNBOUNDSOCK`](#srt_eunboundsock) is reported). |
-| [`SRT_ECONNSOCK`](#srt_econnsock) | The socket is already connected. |
+| [`SRT_ECONNSOCK`](#srt_econnsock) | The socket is currently being used to establish a connection (like by `srt_connect`) |
| [`SRT_EDUPLISTEN`](#srt_eduplisten) | The address used in [`srt_bind`](#srt_bind) by this socket is already occupied by another listening socket.
Binding multiple sockets to one IP address and port is allowed, as long as
[`SRTO_REUSEADDR`](API-socket-options.md#SRTO_REUSEADDRS) is set to true, but only one of these sockets can be set up as a listener. |
|
|
|
diff --git a/docs/build/build-options.md b/docs/build/build-options.md
index 05fcf8be4..2ec4d454a 100644
--- a/docs/build/build-options.md
+++ b/docs/build/build-options.md
@@ -20,12 +20,22 @@ document and in the [SRT CookBook](https://srtlab.github.io/srt-cookbook/getting
## Building as a subproject
The CMake tool offers the ability to add a complete project as a subdirectory.
-Variables used by the SRT project in this case remain in their own scope, but
-all variables from the parent scope are reflected. In order to prevent name
-clashes for option-designating variables, SRT provides a namespace-like
-prefixing for the optional variables it uses. If you want to configure optional
-variables from the level of `CMakeLists.txt` of the parent project, use the
-`LIBSRT_` prefix for the option names.
+If you do this with SRT, note that all variables that can be optionally set
+will get values from the parent configuration file including the one from SRT.
+
+To allow isolation of these variables and setting them explicitly to desired
+values in case when the parent project uses variables with the same names,
+there's a special feature provided: set the desired variables for the SRT
+project using `LIBSRT_` prefix - this way they will get the values to the
+right variables, visible only in the scope of the SRT build configuration.
+
+NOTE: This feature needs to be generally enabled by:
+
+```
+set (LIBSRT_ENABLE_IMPORT_VARIABLES 1)
+```
+
+otherwise all other variables with `LIBSRT_` prefix will be ignored.
This will not prevent the variables from being seen as derived in SRT project
scope, but if you explicitly set a variable this way, it will be set to the
@@ -34,9 +44,10 @@ parent project, and it will also override (locally in SRT project only) any
value of a variable with the same name in the parent project.
For example, if you want to set `ENABLE_SHARED=OFF` in the parent project,
-simply do:
+add this before importing the SRT project:
```
+set (LIBSRT_ENABLE_IMPORT_VARIABLES 1)
set (LIBSRT_ENABLE_SHARED OFF)
```
diff --git a/scripts/codespell/codespell.cfg b/scripts/codespell/codespell.cfg
index a33874609..44f2ec937 100644
--- a/scripts/codespell/codespell.cfg
+++ b/scripts/codespell/codespell.cfg
@@ -6,9 +6,11 @@ builtin = clear,rare,informal,code
# Ignore words listed in this file.
ignore-words = ./scripts/codespell/codespell_whitelist.txt
+ignore-regex = TEST\(.*\)
# Add custom dictionary file.
dictionary = ./scripts/codespell/codespell_dictionary.txt,-
# Skip checking files or directories.
skip = ./build/*,./.git/*
+
diff --git a/srtcore/api.cpp b/srtcore/api.cpp
index 80d41582b..cc3bd49b7 100644
--- a/srtcore/api.cpp
+++ b/srtcore/api.cpp
@@ -1144,27 +1144,34 @@ int srt::CUDTUnited::listen(const SRTSOCKET u, int backlog)
// it could have changed the state. It could be also set listen in another
// thread, so check it out.
- // do nothing if the socket is already listening
- if (s->m_Status == SRTS_LISTENING)
- return 0;
-
- // a socket can listen only if is in OPENED status
- if (s->m_Status != SRTS_OPENED)
- throw CUDTException(MJ_NOTSUP, MN_ISUNBOUND, 0);
-
- // [[using assert(s->m_Status == OPENED)]];
-
- // listen is not supported in rendezvous connection setup
if (s->core().m_config.bRendezvous)
throw CUDTException(MJ_NOTSUP, MN_ISRENDEZVOUS, 0);
- s->m_uiBackLog = backlog;
-
- // [[using assert(s->m_Status == OPENED)]]; // (still, unchanged)
+ switch(s->m_Status)
+ {
+ case SRTS_INIT:
+ throw CUDTException(MJ_NOTSUP, MN_ISUNBOUND, 0);
+ break;
+ case SRTS_OPENED:
+ s->m_uiBackLog = backlog;
+ s->core().setListenState(); // propagates CUDTException,
+ s->m_Status = SRTS_LISTENING;
+ break;
+ case SRTS_LISTENING:
+ s->m_uiBackLog = backlog;
+ break;
+ case SRTS_CONNECTING:
+ case SRTS_CONNECTED:
+ throw CUDTException(MJ_NOTSUP, MN_ISCONNECTED, 0);
+ break;
+ case SRTS_BROKEN:
+ case SRTS_CLOSING:
+ case SRTS_CLOSED:
+ case SRTS_NONEXIST:
+ throw CUDTException(MJ_SETUP, MN_CLOSED, 0);
+ break;
+ }
- s->core().setListenState(); // propagates CUDTException,
- // if thrown, remains in OPENED state if so.
- s->m_Status = SRTS_LISTENING;
return 0;
}
diff --git a/srtcore/common.cpp b/srtcore/common.cpp
index 23b341313..b301b80a9 100644
--- a/srtcore/common.cpp
+++ b/srtcore/common.cpp
@@ -93,7 +93,9 @@ m_iMinor(minor)
m_iErrno = NET_ERROR;
else
m_iErrno = err;
- HLOGC(aclog.Debug, log << "CREATED SRT EXCEPTION: " << (1000*major+minor) << " errno=" << m_iErrno);
+ // XXX No logging allowed because this constructor can be also used for
+ // initializing global object. That problem should be solved separately.
+ // HLOGC(aclog.Debug, log << "CREATED SRT EXCEPTION: " << (1000*major+minor) << " errno=" << m_iErrno);
}
const char* srt::CUDTException::getErrorMessage() const ATR_NOTHROW
diff --git a/srtcore/logging.h b/srtcore/logging.h
index 7782245a2..dd9be95a8 100644
--- a/srtcore/logging.h
+++ b/srtcore/logging.h
@@ -189,6 +189,7 @@ struct SRT_API LogDispatcher
~LogDispatcher()
{
+ src_config = NULL; // Allow to call CheckEnabled after destruction
}
bool CheckEnabled();
@@ -390,6 +391,12 @@ struct LogDispatcher::Proxy
#endif
+
+// IMPORTANT:
+// 1. Logger objects are only allowed to be global. The CheckEnabled
+// method RELIES ON THAT it may run before the Logger() constructor is run.
+// 2. Destructor resets src_config to NULL to prevent any logging instruction
+// to access the facility after destruction.
class Logger
{
int m_fa;
@@ -425,12 +432,16 @@ inline bool LogDispatcher::CheckEnabled()
// when the enabler check is tested here. Worst case, the log
// will be printed just a moment after it was turned off.
const LogConfig* config = src_config; // to enforce using const operator[]
- config->lock();
- int configured_enabled_fa = config->enabled_fa[fa];
- int configured_maxlevel = config->max_level;
- config->unlock();
+ if (config)
+ {
+ config->lock();
+ int configured_enabled_fa = config->enabled_fa[fa];
+ int configured_maxlevel = config->max_level;
+ config->unlock();
- return configured_enabled_fa && level <= configured_maxlevel;
+ return configured_enabled_fa && level <= configured_maxlevel;
+ }
+ return false;
}
diff --git a/test/test_connection_timeout.cpp b/test/test_connection_timeout.cpp
index 281376ce1..2c44baaa4 100644
--- a/test/test_connection_timeout.cpp
+++ b/test/test_connection_timeout.cpp
@@ -390,4 +390,30 @@ TEST(TestConnectionAPI, Accept)
srt_cleanup();
}
+TEST(TestConnectionAPI, Listen)
+{
+ using namespace std::chrono;
+ using namespace srt;
+ srt_startup();
+
+ SRTSOCKET s = srt_create_socket();
+ int listen_stat1, listen_stat2, listen_stat3;
+
+ sockaddr_any sa = srt::CreateAddr("localhost", 5555, AF_INET);
+
+ ASSERT_NE(srt_bind(s, sa.get(), sa.size()), -1);
+ listen_stat1 = srt_listen(s, 1);
+ listen_stat2 = srt_listen(s, 5);
+ srt_close(s);
+ listen_stat3 = srt_listen(s, 5);
+
+ int err = srt_getlasterror(NULL);
+ std::cout << "Listen after close error: " << srt_strerror(err, 0) << std::endl;
+
+ EXPECT_EQ(listen_stat1, 0);
+ EXPECT_EQ(listen_stat2, 0);
+ EXPECT_EQ(listen_stat3, -1);
+
+ srt_cleanup();
+}