メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcThreadLock.c

説明を見る。
00001 
00008 #define DKUTIL_C_THREAD_LOCK_C
00009 
00010 #include "dkcThreadLock.h"
00011 #include "dkcStdio.h"
00012 
00013 
00014 
00015 DKC_THREAD_LOCK * WINAPI dkcAllocThreadLock(){
00016     DKC_THREAD_LOCK *p = (DKC_THREAD_LOCK *)dkcAllocate(sizeof(DKC_THREAD_LOCK));
00017     if(NULL==p){
00018         return NULL;
00019     }
00020 #ifdef WIN32
00021     InitializeCriticalSection(&(p->m_csCriticalSection));
00022 
00023 #else
00024     pthread_mutex_init(&(p->mMutex), NULL);  // POSIX
00025 
00026 #endif
00027     p->mLockedThread = dkcdINVALID_THREAD_ID;
00028     p->mLockCount   = 0;
00029     
00030     return p;
00031 }
00032 
00033 int WINAPI dkcFreeThreadLock(DKC_THREAD_LOCK **pp){
00034     const char *asstr = "dkcThreadLockをLockした回数だけUnlockしないまま終了している";
00035     if(NULL==pp || NULL==*pp){
00036         return edk_ArgumentException;
00037     }
00038     if ((*pp)->mLockCount!=0) {
00039         int i;
00040         dkcmNOT_ASSERT(asstr);
00041         for(i=0;i<(*pp)->mLockCount;i++){
00042             dkcThreadLock_Unlock((*pp));
00043         }
00044     }
00045 #ifdef WIN32
00046     DeleteCriticalSection(&((*pp)->m_csCriticalSection));
00047 #else
00048     pthread_mutex_destroy(&((*pp)->mMutex));
00049 #endif
00050     if ((*pp)->mLockCount!=0) {
00051         dkcmFORCE_NOT_ASSERT(asstr);
00052     }
00053     return dkcFree((void **)pp);
00054 }
00055 
00056 void WINAPI dkcThreadLock_Lock(DKC_THREAD_LOCK *p){
00057     dkcmFORCE_NOT_ASSERT(NULL==p);
00058 #ifdef WIN32    
00059     EnterCriticalSection(&(p->m_csCriticalSection));
00060     //  ↑異なるスレッドからここに入ってくることはできない
00061     //  (CriticalSectionの定義より)
00062 #else
00063     pthread_mutex_lock(&(p->mMutex));
00064     
00065 #endif
00066     p->mLockedThread = dkcGetThreadID();
00067 
00068     p->mLockCount++;
00069 }
00070 
00071 
00072 void WINAPI dkcThreadLock_Unlock(DKC_THREAD_LOCK *p){
00073     dkcmFORCE_NOT_ASSERT(NULL==p);
00074 
00075     if (p->mLockCount==0){
00076         dkcmNOT_ASSERT("CriticalSectionManagerをEnterしていないのにLeaveしている");
00077     }
00078 
00079     if ((--(p->mLockCount))==0) {
00080         p->mLockedThread = dkcdINVALID_THREAD_ID;
00081     }
00082 #ifdef WIN32    
00083     //  ↑Leaveした直後に他スレッドがEnterする可能性がある
00084     LeaveCriticalSection(&(p->m_csCriticalSection));
00085 #else
00086     pthread_mutex_unlock(&(p->mMutex));
00087 #endif
00088 }
00089 
00090 /*
00091 BOOL WINAPI dkcThreadLockIsInited(DKC_THREAD_LOCK *){
00092 
00093 }
00094 */
00095 BOOL WINAPI dkcThreadLockIsLockedByThisThread(DKC_THREAD_LOCK *p)
00096 {
00097     dkctThreadID dw;
00098 
00099     dkcmFORCE_NOT_ASSERT(NULL==p);
00100     dw = dkcGetThreadID();
00101 
00102     return (p->mLockedThread == dw);
00103 }
00104 
00105 
00106 /*
00107 static CRITICAL_SECTION g_csCriticalSection;
00108 static DWORD                g_dwLockedThread = 0;   //  LockしているThreadId(0:非Lock)
00109 static int                  gLockCount = 0;     //  Lockされている回数
00110     //  (同一スレッドならば複数回Lockできるので)
00111 //初期化しているかどうかフラグ。
00112 static BOOL gInited = FALSE;
00113 
00114 
00115 
00116 static void Init(){
00117     {
00118         if(TRUE==gInited){return;}
00119     }
00120     InitializeCriticalSection(&g_csCriticalSection);
00121     g_dwLockedThread = (DWORD)-1;
00122     gLockCount  = 0;
00123 #   ifdef DEBUG
00124     ODS("dkcLockThreadInit\n");
00125 #   endif
00126     gInited = TRUE;
00127 }
00128 
00129 static void End(){
00130     {
00131         if(FALSE==gInited){return;}
00132     }
00133     DeleteCriticalSection(&g_csCriticalSection);
00134     gInited = FALSE;
00135     memset(&g_csCriticalSection,0,sizeof(g_csCriticalSection));
00136     if (gLockCount!=0) {
00137         dkcmNOT_ASSERT("dkcThreadLockをLockした回数だけUnlockしないまま終了している");
00138     }
00139 #   ifdef DEBUG
00140     ODS("dkcLockThreadEnd\n");
00141 #   endif
00142 }
00143 
00144 
00146 static void Enter(){
00147     if(FALSE==gInited){
00148         dkcmFORCE_NOT_ASSERT("dkcThreadLockInit()で初期化していない");
00149         return;
00150     }
00151     EnterCriticalSection(&g_csCriticalSection);
00152     
00153     g_dwLockedThread = GetCurrentThreadId();
00154     //  ↑異なるスレッドからここに入ってくることはできない
00155     //  (CriticalSectionの定義より)
00156     gLockCount++;
00157 
00158 }
00159 
00161 static void Leave(){
00162     if(FALSE==gInited){
00163         dkcmFORCE_NOT_ASSERT("dkcThreadLockInit()で初期化していない");
00164         return;
00165     }
00166     if (gLockCount==0){
00167         dkcmNOT_ASSERT("CriticalSectionManagerをEnterしていないのにLeaveしている");
00168     }
00169 
00170     if (--gLockCount==0) {
00171         g_dwLockedThread = (DWORD)-1;
00172     }
00173     //  ↑Leaveした直後に他スレッドがEnterする可能性がある
00174     LeaveCriticalSection(&g_csCriticalSection);
00175 }
00176 
00177 BOOL WINAPI dkcThreadLockIsLockedByThisThread(){
00178     DWORD dw = GetCurrentThreadId();
00179     return (g_dwLockedThread == dw);
00180 }
00181 
00182 BOOL WINAPI dkcThreadLockIsInited()
00183 {
00184     return gInited;
00185 }
00186 
00187 void WINAPI dkcThreadLockInit(){
00188     Init();
00189 }
00190 
00191 void WINAPI dkcThreadLock_Lock(){
00192     Enter();
00193 }
00194 
00195 void WINAPI dkcThreadLock_Unlock(){
00196     Leave();
00197 }
00198 
00199 void WINAPI dkcThreadLockEnd(){
00200     End();
00201 }
00202 */

dkutil_cに対してMon Jan 16 00:39:54 2006に生成されました。  doxygen 1.4.4