[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / SectionLoader.cpp
blob5612512cf13181650894e5e38ee31f73138f01f7
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "SectionLoader.h"
11 #include "cores/DllLoader/DllLoaderContainer.h"
12 #include "utils/GlobalsHandling.h"
13 #include "utils/StringUtils.h"
14 #include "utils/log.h"
16 #include <mutex>
18 #define g_sectionLoader XBMC_GLOBAL_USE(CSectionLoader)
20 // delay for unloading dll's
21 #define UNLOAD_DELAY 30*1000 // 30 sec.
23 //Define this to get logging on all calls to load/unload sections/dlls
24 //#define LOGALL
26 CSectionLoader::CSectionLoader(void) = default;
28 CSectionLoader::~CSectionLoader(void)
30 UnloadAll();
33 LibraryLoader *CSectionLoader::LoadDLL(const std::string &dllname, bool bDelayUnload /*=true*/, bool bLoadSymbols /*=false*/)
35 std::unique_lock<CCriticalSection> lock(g_sectionLoader.m_critSection);
37 if (dllname.empty()) return NULL;
38 // check if it's already loaded, and increase the reference count if so
39 for (int i = 0; i < (int)g_sectionLoader.m_vecLoadedDLLs.size(); ++i)
41 CDll& dll = g_sectionLoader.m_vecLoadedDLLs[i];
42 if (StringUtils::EqualsNoCase(dll.m_strDllName, dllname))
44 dll.m_lReferenceCount++;
45 return dll.m_pDll;
49 // ok, now load the dll
50 CLog::Log(LOGDEBUG, "SECTION:LoadDLL({})", dllname);
51 LibraryLoader* pDll = DllLoaderContainer::LoadModule(dllname.c_str(), NULL, bLoadSymbols);
52 if (!pDll)
53 return NULL;
55 CDll newDLL;
56 newDLL.m_strDllName = dllname;
57 newDLL.m_lReferenceCount = 1;
58 newDLL.m_bDelayUnload=bDelayUnload;
59 newDLL.m_pDll=pDll;
60 g_sectionLoader.m_vecLoadedDLLs.push_back(newDLL);
62 return newDLL.m_pDll;
65 void CSectionLoader::UnloadDLL(const std::string &dllname)
67 std::unique_lock<CCriticalSection> lock(g_sectionLoader.m_critSection);
69 if (dllname.empty()) return;
70 // check if it's already loaded, and decrease the reference count if so
71 for (int i = 0; i < (int)g_sectionLoader.m_vecLoadedDLLs.size(); ++i)
73 CDll& dll = g_sectionLoader.m_vecLoadedDLLs[i];
74 if (StringUtils::EqualsNoCase(dll.m_strDllName, dllname))
76 dll.m_lReferenceCount--;
77 if (0 == dll.m_lReferenceCount)
79 if (dll.m_bDelayUnload)
80 dll.m_unloadDelayStartTick = std::chrono::steady_clock::now();
81 else
83 CLog::Log(LOGDEBUG, "SECTION:UnloadDll({})", dllname);
84 if (dll.m_pDll)
85 DllLoaderContainer::ReleaseModule(dll.m_pDll);
86 g_sectionLoader.m_vecLoadedDLLs.erase(g_sectionLoader.m_vecLoadedDLLs.begin() + i);
89 return;
95 void CSectionLoader::UnloadDelayed()
97 std::unique_lock<CCriticalSection> lock(g_sectionLoader.m_critSection);
99 // check if we can unload any unreferenced dlls
100 for (int i = 0; i < (int)g_sectionLoader.m_vecLoadedDLLs.size(); ++i)
102 CDll& dll = g_sectionLoader.m_vecLoadedDLLs[i];
103 auto now = std::chrono::steady_clock::now();
104 auto duration =
105 std::chrono::duration_cast<std::chrono::milliseconds>(now - dll.m_unloadDelayStartTick);
106 if (dll.m_lReferenceCount == 0 && duration.count() > UNLOAD_DELAY)
108 CLog::Log(LOGDEBUG, "SECTION:UnloadDelayed(DLL: {})", dll.m_strDllName);
110 if (dll.m_pDll)
111 DllLoaderContainer::ReleaseModule(dll.m_pDll);
112 g_sectionLoader.m_vecLoadedDLLs.erase(g_sectionLoader.m_vecLoadedDLLs.begin() + i);
113 return;
118 void CSectionLoader::UnloadAll()
120 // delete the dll's
121 std::unique_lock<CCriticalSection> lock(g_sectionLoader.m_critSection);
122 std::vector<CDll>::iterator it = g_sectionLoader.m_vecLoadedDLLs.begin();
123 while (it != g_sectionLoader.m_vecLoadedDLLs.end())
125 CDll& dll = *it;
126 if (dll.m_pDll)
127 DllLoaderContainer::ReleaseModule(dll.m_pDll);
128 it = g_sectionLoader.m_vecLoadedDLLs.erase(it);