2 * Copyright (C) 2005-2008 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "threads/SystemClock.h"
24 #include "SectionLoader.h"
25 #include "cores/DllLoader/DllLoaderContainer.h"
26 #include "threads/SingleLock.h"
27 #include "utils/log.h"
28 #include "utils/TimeUtils.h"
32 #define g_sectionLoader XBMC_GLOBAL_USE(CSectionLoader)
34 // delay for unloading dll's
35 #define UNLOAD_DELAY 30*1000 // 30 sec.
37 //Define this to get loggin on all calls to load/unload sections/dlls
40 CSectionLoader::CSectionLoader(void)
43 CSectionLoader::~CSectionLoader(void)
48 bool CSectionLoader::IsLoaded(const CStdString& strSection)
50 CSingleLock lock(g_sectionLoader.m_critSection);
52 for (int i = 0; i < (int)g_sectionLoader.m_vecLoadedSections.size(); ++i)
54 CSection& section = g_sectionLoader.m_vecLoadedSections[i];
55 if (section.m_strSectionName == strSection && section.m_lReferenceCount > 0) return true;
60 bool CSectionLoader::Load(const CStdString& strSection)
62 CSingleLock lock(g_sectionLoader.m_critSection);
64 for (int i = 0; i < (int)g_sectionLoader.m_vecLoadedSections.size(); ++i)
66 CSection& section = g_sectionLoader.m_vecLoadedSections[i];
67 if (section.m_strSectionName == strSection)
71 CLog::Log(LOGDEBUG,"SECTION:LoadSection(%s) count:%i\n", strSection.c_str(), section.m_lReferenceCount);
74 section.m_lReferenceCount++;
80 if ( NULL == XLoadSection(strSection.c_str() ) )
82 CLog::Log(LOGDEBUG,"SECTION:LoadSection(%s) load failed!!\n", strSection.c_str());
85 HANDLE hHandle = XGetSectionHandle(strSection.c_str());
87 CLog::Log(LOGDEBUG,"SECTION:Section %s loaded count:1 size:%i\n", strSection.c_str(), XGetSectionSize(hHandle) );
91 newSection.m_strSectionName = strSection;
92 newSection.m_lReferenceCount = 1;
93 g_sectionLoader.m_vecLoadedSections.push_back(newSection);
97 void CSectionLoader::Unload(const CStdString& strSection)
99 CSingleLock lock(g_sectionLoader.m_critSection);
100 if (!CSectionLoader::IsLoaded(strSection)) return ;
102 ivecLoadedSections i;
103 i = g_sectionLoader.m_vecLoadedSections.begin();
104 while (i != g_sectionLoader.m_vecLoadedSections.end())
106 CSection& section = *i;
107 if (section.m_strSectionName == strSection)
110 CLog::Log(LOGDEBUG,"SECTION:FreeSection(%s) count:%i\n", strSection.c_str(), section.m_lReferenceCount);
112 section.m_lReferenceCount--;
113 if ( 0 == section.m_lReferenceCount)
115 section.m_unloadDelayStartTick = XbmcThreads::SystemClockMillis();
123 LibraryLoader *CSectionLoader::LoadDLL(const CStdString &dllname, bool bDelayUnload /*=true*/, bool bLoadSymbols /*=false*/)
125 CSingleLock lock(g_sectionLoader.m_critSection);
127 if (!dllname) return NULL;
128 // check if it's already loaded, and increase the reference count if so
129 for (int i = 0; i < (int)g_sectionLoader.m_vecLoadedDLLs.size(); ++i)
131 CDll& dll = g_sectionLoader.m_vecLoadedDLLs[i];
132 if (dll.m_strDllName.Equals(dllname))
134 dll.m_lReferenceCount++;
139 // ok, now load the dll
140 CLog::Log(LOGDEBUG, "SECTION:LoadDLL(%s)\n", dllname.c_str());
141 LibraryLoader* pDll = DllLoaderContainer::LoadModule(dllname.c_str(), NULL, bLoadSymbols);
146 newDLL.m_strDllName = dllname;
147 newDLL.m_lReferenceCount = 1;
148 newDLL.m_bDelayUnload=bDelayUnload;
150 g_sectionLoader.m_vecLoadedDLLs.push_back(newDLL);
152 return newDLL.m_pDll;
155 void CSectionLoader::UnloadDLL(const CStdString &dllname)
157 CSingleLock lock(g_sectionLoader.m_critSection);
159 if (!dllname) return;
160 // check if it's already loaded, and decrease the reference count if so
161 for (int i = 0; i < (int)g_sectionLoader.m_vecLoadedDLLs.size(); ++i)
163 CDll& dll = g_sectionLoader.m_vecLoadedDLLs[i];
164 if (dll.m_strDllName.Equals(dllname))
166 dll.m_lReferenceCount--;
167 if (0 == dll.m_lReferenceCount)
169 if (dll.m_bDelayUnload)
170 dll.m_unloadDelayStartTick = XbmcThreads::SystemClockMillis();
173 CLog::Log(LOGDEBUG,"SECTION:UnloadDll(%s)", dllname.c_str());
175 DllLoaderContainer::ReleaseModule(dll.m_pDll);
176 g_sectionLoader.m_vecLoadedDLLs.erase(g_sectionLoader.m_vecLoadedDLLs.begin() + i);
185 void CSectionLoader::UnloadDelayed()
187 CSingleLock lock(g_sectionLoader.m_critSection);
189 ivecLoadedSections i = g_sectionLoader.m_vecLoadedSections.begin();
190 while( i != g_sectionLoader.m_vecLoadedSections.end() )
192 CSection& section = *i;
193 if( section.m_lReferenceCount == 0 && XbmcThreads::SystemClockMillis() - section.m_unloadDelayStartTick > UNLOAD_DELAY)
195 CLog::Log(LOGDEBUG,"SECTION:UnloadDelayed(SECTION: %s)", section.m_strSectionName.c_str());
197 XFreeSection(section.m_strSectionName.c_str());
199 i = g_sectionLoader.m_vecLoadedSections.erase(i);
205 // check if we can unload any unreferenced dlls
206 for (int i = 0; i < (int)g_sectionLoader.m_vecLoadedDLLs.size(); ++i)
208 CDll& dll = g_sectionLoader.m_vecLoadedDLLs[i];
209 if (dll.m_lReferenceCount == 0 && XbmcThreads::SystemClockMillis() - dll.m_unloadDelayStartTick > UNLOAD_DELAY)
211 CLog::Log(LOGDEBUG,"SECTION:UnloadDelayed(DLL: %s)", dll.m_strDllName.c_str());
214 DllLoaderContainer::ReleaseModule(dll.m_pDll);
215 g_sectionLoader.m_vecLoadedDLLs.erase(g_sectionLoader.m_vecLoadedDLLs.begin() + i);
221 void CSectionLoader::UnloadAll()
223 ivecLoadedSections i;
224 i = g_sectionLoader.m_vecLoadedSections.begin();
225 while (i != g_sectionLoader.m_vecLoadedSections.end())
227 CSection& section = *i;
228 //g_sectionLoader.m_vecLoadedSections.erase(i);
229 CLog::Log(LOGDEBUG,"SECTION:UnloadAll(SECTION: %s)", section.m_strSectionName.c_str());
231 XFreeSection(section.m_strSectionName.c_str());
233 i = g_sectionLoader.m_vecLoadedSections.erase(i);
237 CSingleLock lock(g_sectionLoader.m_critSection);
238 vector<CDll>::iterator it = g_sectionLoader.m_vecLoadedDLLs.begin();
239 while (it != g_sectionLoader.m_vecLoadedDLLs.end())
242 CLog::Log(LOGDEBUG,"SECTION:UnloadAll(DLL: %s)", dll.m_strDllName.c_str());
244 DllLoaderContainer::ReleaseModule(dll.m_pDll);
245 it = g_sectionLoader.m_vecLoadedDLLs.erase(it);