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

# 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 */