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.
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"
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
26 CSectionLoader::CSectionLoader(void) = default;
28 CSectionLoader::~CSectionLoader(void)
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
++;
49 // ok, now load the dll
50 CLog::Log(LOGDEBUG
, "SECTION:LoadDLL({})", dllname
);
51 LibraryLoader
* pDll
= DllLoaderContainer::LoadModule(dllname
.c_str(), NULL
, bLoadSymbols
);
56 newDLL
.m_strDllName
= dllname
;
57 newDLL
.m_lReferenceCount
= 1;
58 newDLL
.m_bDelayUnload
=bDelayUnload
;
60 g_sectionLoader
.m_vecLoadedDLLs
.push_back(newDLL
);
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();
83 CLog::Log(LOGDEBUG
, "SECTION:UnloadDll({})", dllname
);
85 DllLoaderContainer::ReleaseModule(dll
.m_pDll
);
86 g_sectionLoader
.m_vecLoadedDLLs
.erase(g_sectionLoader
.m_vecLoadedDLLs
.begin() + i
);
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();
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
);
111 DllLoaderContainer::ReleaseModule(dll
.m_pDll
);
112 g_sectionLoader
.m_vecLoadedDLLs
.erase(g_sectionLoader
.m_vecLoadedDLLs
.begin() + i
);
118 void CSectionLoader::UnloadAll()
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())
127 DllLoaderContainer::ReleaseModule(dll
.m_pDll
);
128 it
= g_sectionLoader
.m_vecLoadedDLLs
.erase(it
);