diff --git a/Common/BlockLock.h b/Common/BlockLock.h index e69de29..c4417c2 100644 --- a/Common/BlockLock.h +++ b/Common/BlockLock.h @@ -0,0 +1,11 @@ +#pragma once + +class CBlockLock +{ +public: + CBlockLock(CRITICAL_SECTION* lock_) : lock(lock_) { EnterCriticalSection(lock); } + ~CBlockLock() { LeaveCriticalSection(lock); } +private: + CRITICAL_SECTION* lock; +}; + diff --git a/Common/EpgDataCap3Util.cpp b/Common/EpgDataCap3Util.cpp index adfa8de..92d9d05 100644 --- a/Common/EpgDataCap3Util.cpp +++ b/Common/EpgDataCap3Util.cpp @@ -181,6 +181,7 @@ DWORD CEpgDataCap3Util::UnInitialize( return ERR_NOT_INIT; } DWORD err = pfnUnInitializeEP3(id); + id = 0; // ← これがないと下の UnLoadDll で再度 UnInitializeEP が呼ばれる UnLoadDll(); return err; } diff --git a/EpgDataCap3/EpgDataCap3/EpgDBUtil.cpp b/EpgDataCap3/EpgDataCap3/EpgDBUtil.cpp index 1b03352..e76276c 100644 --- a/EpgDataCap3/EpgDataCap3/EpgDBUtil.cpp +++ b/EpgDataCap3/EpgDataCap3/EpgDBUtil.cpp @@ -5,6 +5,7 @@ #include "../../Common/StringUtil.h" #include "../../Common/TimeUtil.h" #include "../../Common/ErrDef.h" +#include "../../Common/BlockLock.h" #include "ARIB8CharDecode.h" CEpgDBUtil::CEpgDBUtil(void) @@ -52,15 +53,6 @@ CEpgDBUtil::~CEpgDBUtil(void) this->serviceDBListSize = 0; } -class CBlockLock -{ -public: - CBlockLock(CRITICAL_SECTION* lock_) : lock(lock_) { EnterCriticalSection(lock); } - ~CBlockLock() { LeaveCriticalSection(lock); } -private: - CRITICAL_SECTION* lock; -}; - void CEpgDBUtil::Clear() { map::iterator itr; diff --git a/EpgDataCap3/EpgDataCap3/EpgDataCap3.cpp b/EpgDataCap3/EpgDataCap3/EpgDataCap3.cpp index 1fffeb9..6bdb6ce 100644 --- a/EpgDataCap3/EpgDataCap3/EpgDataCap3.cpp +++ b/EpgDataCap3/EpgDataCap3/EpgDataCap3.cpp @@ -5,43 +5,112 @@ #include "EpgDataCap3Main.h" #include "../../Common/ErrDef.h" +#include "../../Common/BlockLock.h" -map g_List; -DWORD g_nextID = 1; - -DWORD GetNextID() +class CInstanceManager { - DWORD nextID = 0xFFFFFFFF; - - map::iterator itr; - itr = g_List.find(g_nextID); - if( itr == g_List.end() ){ - nextID = g_nextID; - g_nextID++; - if( g_nextID == 0 || g_nextID == 0xFFFFFFFF){ - g_nextID = 1; +public: + static const DWORD INVALID_ID = 0xFFFFFFFF; + + CInstanceManager() + { + InitializeCriticalSection(&(this->m_lock)); + this->m_nextID = 1; + } + + ~CInstanceManager() + { + DeleteCriticalSection(&(this->m_lock)); + } + + DWORD initialize(BOOL asyncFlag, DWORD *id) + { + CBlockLock lock(&(this->m_lock)); + + std::shared_ptr ptr; + + *id = INVALID_ID; + + try { + ptr = std::make_shared(); + } catch (std::bad_alloc &) { + return ERR_FALSE; + } + + DWORD err = ptr->Initialize(asyncFlag); + if (err != NO_ERR) { + return err; + } + + try { + *id = this->getNextID(); + this->m_list.insert(std::make_pair(*id,ptr)); + } catch (std::bad_alloc &) { + *id = INVALID_ID; + return ERR_FALSE; + } + + return err; + } + + DWORD uninitialize(DWORD id) + { + CBlockLock lock(&(this->m_lock)); + + std::shared_ptr ptr = this->find(id); + if (ptr == NULL) { + return ERR_NOT_INIT; + } + + DWORD err = ptr->UnInitialize(); + this->m_list.erase(id); + + return err; + } + + std::shared_ptr find(DWORD id) + { + CBlockLock lock(&(this->m_lock)); + + if (this->m_list.count(id) == 0) { + return NULL; } - }else{ - for( DWORD i=1; i<0xFFFFFFFF; i++ ){ - itr = g_List.find(g_nextID); - if( itr == g_List.end() ){ - nextID = g_nextID; - g_nextID++; - if( g_nextID == 0 || g_nextID == 0xFFFFFFFF){ - g_nextID = 1; - } - break; - }else{ - g_nextID++; + + return this->m_list.at(id); + } + +protected: + std::map > m_list; + DWORD m_nextID; + CRITICAL_SECTION m_lock; + + DWORD getNextID() + { + CBlockLock lock(&(this->m_lock)); + + DWORD nextID = INVALID_ID; + int count = 0; + do { + if (this->m_list.count(this->m_nextID) == 0) { + nextID = this->m_nextID; } - if( g_nextID == 0 || g_nextID == 0xFFFFFFFF){ - g_nextID = 1; + + this->m_nextID += 1; + if ((this->m_nextID == 0)|| (this->m_nextID == INVALID_ID)) { + this->m_nextID = 1; } - } + count += 1; + + // 65536 回試してダメだったら断念 + // 1 プロセスから (2^16) 以上のインスタンスを同時に作成することはないはず + + } while ((nextID == INVALID_ID) && (count < (1<<16))); + + return nextID; } +}; - return nextID; -} +CInstanceManager g_instMng; //DLLの初期化 //戻り値: @@ -54,16 +123,14 @@ DWORD WINAPI InitializeEP( DWORD* id ) { - if( id == NULL ){ + if (id == NULL) { return ERR_INVALID_ARG; } - CEpgDataCap3Main* main = new CEpgDataCap3Main; - DWORD err = main->Initialize(asyncFlag); - if( err == NO_ERR ){ - *id = GetNextID(); - g_List.insert(pair(*id, main)); - } + DWORD err = g_instMng.initialize(asyncFlag, id); + + _OutputDebugString(L"EgpDataCap3.dll [InitializeEP : id=%d]\n", *id); + return err; } @@ -76,17 +143,9 @@ DWORD WINAPI UnInitializeEP( DWORD id ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ - return ERR_NOT_INIT; - } - - DWORD err = itr->second->UnInitialize(); - - SAFE_DELETE(itr->second); + _OutputDebugString(L"EgpDataCap3.dll [UnInitializeEP : id=%d]\n", id); - g_List.erase(itr); + DWORD err = g_instMng.uninitialize(id); return err; } @@ -103,13 +162,12 @@ DWORD WINAPI AddTSPacketEP( DWORD size ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return ERR_NOT_INIT; } - return itr->second->AddTSPacket(data, size); + return ptr->AddTSPacket(data, size); } //解析データの現在のストリームIDを取得する @@ -124,13 +182,12 @@ DWORD WINAPI GetTSIDEP( WORD* transportStreamID ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return ERR_NOT_INIT; } - return itr->second->GetTSID(originalNetworkID, transportStreamID); + return ptr->GetTSID(originalNetworkID, transportStreamID); } //自ストリームのサービス一覧を取得する @@ -146,13 +203,12 @@ DWORD WINAPI GetServiceListActualEP( SERVICE_INFO** serviceList ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return ERR_NOT_INIT; } - return itr->second->GetServiceListActual(serviceListSize, serviceList); + return ptr->GetServiceListActual(serviceListSize, serviceList); } //蓄積されたEPG情報のあるサービス一覧を取得する @@ -169,13 +225,12 @@ DWORD WINAPI GetServiceListEpgDBEP( SERVICE_INFO** serviceList ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return ERR_NOT_INIT; } - return itr->second->GetServiceListEpgDB(serviceListSize, serviceList); + return ptr->GetServiceListEpgDB(serviceListSize, serviceList); } //指定サービスの全EPG情報を取得する @@ -197,13 +252,12 @@ DWORD WINAPI GetEpgInfoListEP( EPG_EVENT_INFO** epgInfoList ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return ERR_NOT_INIT; } - return itr->second->GetEpgInfoList(originalNetworkID, transportStreamID, serviceID, epgInfoListSize, epgInfoList); + return ptr->GetEpgInfoList(originalNetworkID, transportStreamID, serviceID, epgInfoListSize, epgInfoList); } //指定サービスの現在or次のEPG情報を取得する @@ -224,13 +278,12 @@ DWORD WINAPI GetEpgInfoEP( EPG_EVENT_INFO** epgInfo ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return ERR_NOT_INIT; } - return itr->second->GetEpgInfo(originalNetworkID, transportStreamID, serviceID, nextFlag, epgInfo); + return ptr->GetEpgInfo(originalNetworkID, transportStreamID, serviceID, nextFlag, epgInfo); } //指定イベントのEPG情報を取得する @@ -254,13 +307,12 @@ DWORD WINAPI SearchEpgInfoEP( EPG_EVENT_INFO** epgInfo ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return ERR_NOT_INIT; } - return itr->second->SearchEpgInfo(originalNetworkID, transportStreamID, serviceID, eventID, pfOnlyFlag, epgInfo); + return ptr->SearchEpgInfo(originalNetworkID, transportStreamID, serviceID, eventID, pfOnlyFlag, epgInfo); } //EPGデータの蓄積状態をリセットする @@ -270,13 +322,12 @@ void WINAPI ClearSectionStatusEP( DWORD id ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ - return ; + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { + return; } - itr->second->ClearSectionStatus(); + ptr->ClearSectionStatus(); } //EPGデータの蓄積状態を取得する @@ -290,13 +341,12 @@ EPG_SECTION_STATUS WINAPI GetSectionStatusEP( BOOL l_eitFlag ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return EpgNoData; } - return itr->second->GetSectionStatus(l_eitFlag); + return ptr->GetSectionStatus(l_eitFlag); } //PC時計を元としたストリーム時間との差を取得する @@ -308,11 +358,10 @@ int WINAPI GetTimeDelayEP( DWORD id ) { - map::iterator itr; - itr = g_List.find(id); - if( itr == g_List.end() ){ + std::shared_ptr ptr = g_instMng.find(id); + if (ptr == NULL) { return EpgNoData; } - return itr->second->GetTimeDelay(); + return ptr->GetTimeDelay(); } \ No newline at end of file diff --git a/EpgDataCap3/EpgDataCap3/EpgDataCap3Main.cpp b/EpgDataCap3/EpgDataCap3/EpgDataCap3Main.cpp index 499a3f3..232d91c 100644 --- a/EpgDataCap3/EpgDataCap3/EpgDataCap3Main.cpp +++ b/EpgDataCap3/EpgDataCap3/EpgDataCap3Main.cpp @@ -1,6 +1,7 @@ #include "StdAfx.h" #include "EpgDataCap3Main.h" +#include "../../Common/BlockLock.h" CEpgDataCap3Main::CEpgDataCap3Main(void) { @@ -16,15 +17,6 @@ CEpgDataCap3Main::~CEpgDataCap3Main(void) DeleteCriticalSection(&this->utilLock); } -class CBlockLock -{ -public: - CBlockLock(CRITICAL_SECTION* lock_) : lock(lock_) { EnterCriticalSection(lock); } - ~CBlockLock() { LeaveCriticalSection(lock); } -private: - CRITICAL_SECTION* lock; -}; - //DLLの初期化 //戻り値: // エラーコード