From 20def32569531949dae4d44439f5224536a73a81 Mon Sep 17 00:00:00 2001 From: Malcolm Bechard Date: Fri, 3 Jan 2025 16:44:25 -0500 Subject: [PATCH] fix missing increment of the reference count on every call to startup() also change how the implicit startup is tracked. The extra change is needed since the startup() calls in srt::CUDT::socket() and srt::CUDT::createGroup would endlessly increment the startup counter as sockets were created. This also adds handling for the case where the user code fails to call srt_startup when initially using the library, but does later on. It better matches up the implicit startup() with an implicit cleanup(). fixes #3098 --- srtcore/api.cpp | 32 +++++++++++++++++++++++--------- srtcore/api.h | 3 +++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/srtcore/api.cpp b/srtcore/api.cpp index bb5dd64fe..ff55f8018 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -180,6 +180,7 @@ srt::CUDTUnited::CUDTUnited() , m_InitLock() , m_iInstanceCount(0) , m_bGCStatus(false) + , m_bImplicitStartup(false) , m_ClosedSockets() { // Socket ID MUST start from a random value @@ -198,12 +199,15 @@ srt::CUDTUnited::CUDTUnited() srt::CUDTUnited::~CUDTUnited() { - // Call it if it wasn't called already. - // This will happen at the end of main() of the application, - // when the user didn't call srt_cleanup(). - if (m_bGCStatus) { - cleanup(); + // If an implicit startup was called, then call a matching cleanup + // This will happen at the end of main() of the application, + // when the user didn't call srt_cleanup() before using the library. + ScopedLock gcinit(m_InitLock); + if (m_bImplicitStartup) + { + cleanup(); + } } releaseMutex(m_GlobControlLock); @@ -233,15 +237,24 @@ string srt::CUDTUnited::CONID(SRTSOCKET sock) return os.str(); } -int srt::CUDTUnited::startup() +void srt::CUDTUnited::implicitStartup() { ScopedLock gcinit(m_InitLock); if (m_bGCStatus) - return 1; + return; + m_bImplicitStartup = true; + startup(); +} +int srt::CUDTUnited::startup() +{ + ScopedLock gcinit(m_InitLock); if (m_iInstanceCount++ > 0) return 1; + if (m_bGCStatus) + return 1; + // Global initialization code #ifdef _WIN32 WORD wVersionRequested; @@ -299,6 +312,7 @@ int srt::CUDTUnited::cleanup() m_GCThread.join(); m_bGCStatus = false; + m_bImplicitStartup = false; // Global destruction code #ifdef _WIN32 @@ -3469,7 +3483,7 @@ int srt::CUDT::cleanup() SRTSOCKET srt::CUDT::socket() { - uglobal().startup(); + uglobal().implicitStartup(); try { @@ -3519,7 +3533,7 @@ srt::CUDTGroup& srt::CUDT::newGroup(const int type) SRTSOCKET srt::CUDT::createGroup(SRT_GROUP_TYPE gt) { // Doing the same lazy-startup as with srt_create_socket() - uglobal().startup(); + uglobal().implicitStartup(); try { diff --git a/srtcore/api.h b/srtcore/api.h index 48e7827f8..9779ec8ca 100644 --- a/srtcore/api.h +++ b/srtcore/api.h @@ -428,6 +428,7 @@ class CUDTUnited CUDTSocket* locateSocket_LOCKED(SRTSOCKET u); CUDTSocket* locatePeer(const sockaddr_any& peer, const SRTSOCKET id, int32_t isn); + void implicitStartup(); #if ENABLE_BONDING CUDTGroup* locateAcquireGroup(SRTSOCKET u, ErrorHandling erh = ERH_RETURN); CUDTGroup* acquireSocketsGroup(CUDTSocket* s); @@ -542,6 +543,8 @@ class CUDTUnited int m_iInstanceCount; // number of startup() called by application SRT_ATTR_GUARDED_BY(m_InitLock) bool m_bGCStatus; // if the GC thread is working (true) + SRT_ATTR_GUARDED_BY(m_InitLock) + bool m_bImplicitStartup; // if startup was implicitly called SRT_ATTR_GUARDED_BY(m_InitLock) sync::CThread m_GCThread;