diff --git a/srtcore/api.cpp b/srtcore/api.cpp index bb5dd64fe..b46ec8b3c 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -198,13 +198,8 @@ 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(); - } + // force cleanup, even if the instance count is > 1 + cleanup(true); releaseMutex(m_GlobControlLock); releaseMutex(m_IDLock); @@ -233,15 +228,24 @@ string srt::CUDTUnited::CONID(SRTSOCKET sock) return os.str(); } -int srt::CUDTUnited::startup() +void srt::CUDTUnited::implicitStartup() +{ + startup(true); +} + +int srt::CUDTUnited::startup(bool implicit) { ScopedLock gcinit(m_InitLock); - if (m_bGCStatus) + + if (implicit && m_iInstanceCount > 0) return 1; if (m_iInstanceCount++ > 0) return 1; + if (m_bGCStatus) + return 1; + // Global initialization code #ifdef _WIN32 WORD wVersionRequested; @@ -268,7 +272,7 @@ int srt::CUDTUnited::startup() return 0; } -int srt::CUDTUnited::cleanup() +int srt::CUDTUnited::cleanup(bool force) { // IMPORTANT!!! // In this function there must be NO LOGGING AT ALL. This function may @@ -280,8 +284,14 @@ int srt::CUDTUnited::cleanup() // executing this procedure. ScopedLock gcinit(m_InitLock); - if (--m_iInstanceCount > 0) - return 0; + if (!force) + { + if (m_iInstanceCount == 0) + return 0; + + if (--m_iInstanceCount > 0) + return 0; + } if (!m_bGCStatus) return 0; @@ -298,6 +308,8 @@ int srt::CUDTUnited::cleanup() CSync::notify_one_relaxed(m_GCStopCond); m_GCThread.join(); + if (force) + m_iInstanceCount = 0; m_bGCStatus = false; // Global destruction code @@ -3469,7 +3481,7 @@ int srt::CUDT::cleanup() SRTSOCKET srt::CUDT::socket() { - uglobal().startup(); + uglobal().implicitStartup(); try { @@ -3519,7 +3531,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..173b97c43 100644 --- a/srtcore/api.h +++ b/srtcore/api.h @@ -257,12 +257,14 @@ class CUDTUnited static std::string CONID(SRTSOCKET sock); /// initialize the UDT library. + /// @param [in] implicit should be set to true for internal implicit startup() calls. /// @return 0 if success, otherwise -1 is returned. - int startup(); + int startup(bool implicit = false); /// release the UDT library. + /// @param [in] force cleanup regardless of the instance count. /// @return 0 if success, otherwise -1 is returned. - int cleanup(); + int cleanup(bool force = false); /// Create a new UDT socket. /// @param [out] pps Variable (optional) to which the new socket will be written, if succeeded @@ -428,6 +430,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);