📄 repository.cpp
字号:
/******************************************************************************** repository.cpp: Repository class*-------------------------------------------------------------------------------* (c)1999-2001 VideoLAN* $Id: repository.cpp,v 1.2 2002/09/26 16:05:34 jpsaman Exp $** Authors: Benoit Steiner <benny@via.ecp.fr>** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version 2* of the License, or (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**-------------------------------------------------------------------------------********************************************************************************//******************************************************************************** C_RepositoryItem****************************************************************************************************************************************************************///------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> C_RepositoryBrowser<Key, Data>::C_RepositoryBrowser(const C_Repository<Key, Data>& cRepository) : m_cKeyIterator(cRepository.m_cItems.CreateIterator()), m_cDataIterator(cRepository.m_cItems.CreateIterator()){ }//------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> Data* C_RepositoryBrowser<Key, Data>::GetNextItem(){ C_HashTableNode<Key, C_RepositoryItem<Data> >* pNode = m_cDataIterator.GetNext(); C_RepositoryItem<Data>* pData = pNode->GetValue(); Data* pItem = pData->GetItem(); return pItem;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------/******************************************************************************** C_Repository********************************************************************************* The locking rules are the following:* - Whenever an item is accessed (Get method) its associated reference counter* is increased. The reference counter can be decreased by calling Release* - When the repository is locked, calls to GetPgrm and ReleasePgrm are delayed.* - Global modifications of the repository (Add, Remove, Empty) are only allowed* to the owner of the repository lock.* - Calls to Remove fails unless the reference counter of the item is 0** Lock checks are only made in DEBUG mode for efficiency reasons*******************************************************************************///------------------------------------------------------------------------------// Usefull macro//------------------------------------------------------------------------------#ifdef DEBUG#define DEBUG_LOCK(pPgrm) \ (pPgrm)->Lock();#define DEBUG_UNLOCK(pPgrm) \ (pPgrm)->UnLock();#else#define DEBUG_LOCK(pPgrm)#define DEBUG_UNLOCK(pPgrm)#endif//------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> void C_Repository<Key, Data>::Lock(){ //printf("Locking dir\n"); m_cLock.Lock();#ifdef DEBUG // Directory locking m_bIsLocked = true; m_pLockOwner = C_Thread::Self();#endif}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> void C_Repository<Key, Data>::UnLock(){ ASSERT(m_bIsLocked); #ifdef DEBUG m_bIsLocked = false;#endif //printf("Unlocking dir\n"); m_cLock.UnLock();}//------------------------------------------------------------------------------// Return GEN_ERR if the program already exist//------------------------------------------------------------------------------template <class Key, class Data> int C_Repository<Key, Data>::Add(const Key& cKey, Data* pItem){ ASSERT(pItem); // The directory should have been locked before ASSERT(m_bIsLocked); ASSERT(m_pLockOwner == C_Thread::Self()); int iRc = NO_ERR; if(m_cItems.Get(cKey) != NULL) { iRc = GEN_ERR; } else { C_RepositoryItem<Data>* pContainer = new C_RepositoryItem<Data>(pItem); m_cItems.Add(cKey, pContainer); } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> int C_Repository<Key, Data>::Remove(const Key& cKey){ // The directory should have been locked before ASSERT(m_bIsLocked); ASSERT(m_pLockOwner == C_Thread::Self()); int iRc = NO_ERR; C_RepositoryItem<Data>* pContainer = m_cItems.Get(cKey); if(!pContainer) { iRc = GEN_ERR; } else { unsigned int iRefCount = pContainer->GetRefCount(); ASSERT(iRefCount == 0); if(iRefCount > 0) iRc = GEN_ERR; else m_cItems.Delete(cKey); } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------/*void C_PgrmDirectory::EmptyPgrmList(){ ASSERT(m_bIsLocked); ASSERT(m_pLockOwner == C_Thread::Self()); for(unsigned int iIndex = 0; iIndex < m_cPgrms.Size(); iIndex++) { m_cPgrms.Delete(iIndex); }}*///------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> Data* C_Repository<Key, Data>::Get(const Key& cKey){ Data* pItem = NULL; // If a lock on the directory is owned, the [] operator should be used instead ASSERT(!(m_bIsLocked && m_pLockOwner == C_Thread::Self())); // First lock the directory to avoid any modification m_cLock.Lock(); //printf("Directory protected\n"); C_RepositoryItem<Data>* pContainer = m_cItems.Get(cKey); if(pContainer) { pContainer->IncreaseRefCount(); pItem = pContainer->GetItem(); } m_cLock.UnLock(); return pItem;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> void C_Repository<Key, Data>::Release(const Key& cKey){ // First lock the directory to avoid any modification m_cLock.Lock(); C_RepositoryItem<Data>* pContainer = m_cItems.Get(cKey); if(pContainer) { pContainer->DecreaseRefCount(); } else { ASSERT(false); } m_cLock.UnLock();}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> Data* C_Repository<Key, Data>::operator [] (const Key& cKey){ ASSERT(m_bIsLocked); ASSERT(m_pLockOwner == C_Thread::Self()); C_RepositoryItem<Data>* pContainer = m_cItems.Get(cKey); ASSERT(pContainer); return pContainer->GetItem();}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> Data* C_Repository<Key, Data>::Find(const Key& cKey){ ASSERT(m_bIsLocked); ASSERT(m_pLockOwner == C_Thread::Self()); C_RepositoryItem<Data>* pContainer = m_cItems.Get(cKey); if(pContainer) return pContainer->GetItem(); else return NULL;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------template <class Key, class Data> C_RepositoryBrowser<Key, Data> C_Repository<Key, Data>::CreateBrowser() const{ ASSERT(m_bIsLocked); ASSERT(m_pLockOwner == C_Thread::Self()); return C_RepositoryBrowser<Key, Data> (*this);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -