📄 semaphor.c
字号:
RETAILMSG( 1, ( "KL_LeaveCriticalSection error: the thread( handle(0x%x), id(0x%x), curproc=%s, ownerproc=%s )is not own CriticalSection.\r\n", lpCurThread->hThread, lpCurThread->dwThreadId, lpCurThread->lpCurProcess->lpszApplicationName, lpCurThread->lpOwnerProcess->lpszApplicationName ) );
DumpCallStack( lpCurThread );
}
}
else
{
ERRORMSG( 1 , ( "KL_LeaveCriticalSection error: null ptr,pc=0x%x,id=0x%x,curproc=%s, ownerproc=%s.\r\n", lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->dwThreadId, lpCurThread->lpCurProcess->lpszApplicationName, lpCurThread->lpOwnerProcess->lpszApplicationName ) );
DumpCallStack( lpCurThread );
}
}
// ********************************************************************
// 声明:DoEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection, BOOL bEntryBlock )
// 参数:
// IN lpCriticalSection - CRITICAL_SECTION结构指针
// IN bEntryBlock - 当不拥有冲突段时,是否退出
// 返回值:
// 当拥有冲突段,返回TRUE; 否则,返回FALSE
// 功能描述:
// 进入冲突段,不管是否拥有,都回退出
// 引用:
// 系统API
// ********************************************************************
static BOOL DoEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection, BOOL bEntryBlock )
{
BOOL bRetv = FALSE;
if( lpCriticalSection )
{
if( lpCriticalSection->dwOwnerThreadId == lpCurThread->dwThreadId ) //当前线程拥有该冲突段吗?
{ //是,简单的将计数器加一
lpCriticalSection->iLockCount++;
bRetv = TRUE;
#ifdef __DEBUG
if( lpCriticalSection->uiFlag & CSF_DEBUG )
{
RETAILMSG( 1, ( "EnterCriticalSection skip:lpcs=0x%x,lpcsName=%s,iLockCount=%d.\r\n", lpCriticalSection, lpCriticalSection->lpcsName, lpCriticalSection->iLockCount ) );
}
#endif
}
else
{ // 不拥有,否
LPSEMAPHORE lpho;
#ifdef __DEBUG
if( lpCriticalSection->uiFlag & CSF_DEBUG )
{
RETAILMSG( 1, ( "CS-wait...:lpcs=0x%x,lpcsName=%s,Owner Thread=0x%x.\r\n", lpCriticalSection, lpCriticalSection->lpcsName, lpCriticalSection->dwOwnerThreadId ) );
}
#endif
#ifdef DEBUG_CRITSEC
if( lpCriticalSection->lpcsName )
{
DWORD dwCurThreadId = KL_GetCurrentThreadId();
RETAILMSG( 1, ( "downcs-enter=%s, cid=0x%x, oid=0x%x, count=%d\r\n", lpCriticalSection->lpcsName, dwCurThreadId, lpCriticalSection->dwOwnerThreadId, lpCriticalSection->iLockCount ) );
}
#endif
if( lpCriticalSection->uiFlag & CSF_KERNEL )//是否是内核自己的创建的
lpho = (LPSEMAPHORE)lpCriticalSection->hSemaphore; //是
else
lpho = (LPSEMAPHORE)HandleToPtr( lpCriticalSection->hSemaphore, -1 ); // 否,用户对象
lpho = GetSemaphoreAndLock( lpho, 0 );
if( lpho )
{
bRetv = DownCrit( lpho, lpCriticalSection, bEntryBlock ); //进入原子操作
ReleaseSemaphoreAndUnlock( lpho );
}
else
{
ERRORMSG( 1 , ( "KL_EnterCriticalSection error: null lpho,id=0x%x,pc=0x%x,proc=%s.\r\n", lpCurThread->dwThreadId, lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->lpCurProcess->lpszApplicationName ) );
DumpCallStack( lpCurThread );
}
#ifdef DEBUG_CRITSEC
if( lpCriticalSection->lpcsName )
{
DWORD dwCurThreadId = KL_GetCurrentThreadId();
RETAILMSG( 1, ( "downcs-exit=%s, cid=0x%x, oid=0x%x, count=%d\r\n", lpCriticalSection->lpcsName, dwCurThreadId, lpCriticalSection->dwOwnerThreadId, lpCriticalSection->iLockCount ) );
}
#endif
}
}
else
{
ERRORMSG( 1 , ( "KL_EnterCriticalSection error: null ptr,pc=0x%x,proc=%s.\r\n", lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->lpCurProcess->lpszApplicationName ) );
DumpCallStack( lpCurThread );
}
return bRetv;
}
// ********************************************************************
// 声明:VOID WINAPI KL_EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
// IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
// 无
// 功能描述:
// 进入冲突段
// 引用:
// 系统API
// ********************************************************************
VOID WINAPI KL_EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
DoEnterCriticalSection( lpCriticalSection, TRUE );
}
// ********************************************************************
// 声明:BOOL WINAPI KL_TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
// IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
// 当拥有冲突段,返回TRUE; 否则,返回FALSE
// 功能描述:
// 进入冲突段,不管是否拥有,都回退出
// 引用:
// 系统API
// ********************************************************************
BOOL WINAPI KL_TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
return DoEnterCriticalSection( lpCriticalSection, FALSE );
}
// ********************************************************************
// 声明:static LPVOID GetThreadSemp( LPTHREAD lpThread )
// 参数:
// IN lpThread - THREAD线程结构指针
// 返回值:
// 信号量对象
// 功能描述:
// 得到线程的信号量
// 引用:
//
// ********************************************************************
static LPVOID GetThreadSemp( LPTHREAD lpThread )
{
return lpThread->lpsemExit;
}
// ********************************************************************
// 声明:LPSEMAPHORE GetSemaphoreAndLock( HANDLE hSem )
// 参数:
// IN hSem - 信号量句柄
// IN uObjType - 对象类型
// 返回值:
// 信号量对象指针
// 功能描述:
// 得到信号量句柄对应的指针并且锁住它
// 引用:
//
// ********************************************************************
#define DEBUG_GetSemaphoreAndLock 0
LPSEMAPHORE GetSemaphoreAndLock( HANDLE hSem, UINT uObjType )
{
LPSEMAPHORE lpSem;
UINT uiSave;
LockIRQSave( &uiSave );
if( uObjType )
lpSem = HandleToPtr( hSem, uObjType );//由句柄得到对象指针
else
lpSem = (LPSEMAPHORE)hSem;
if( lpSem )
{
if( lpSem->nRefCount )
lpSem->nRefCount++;
else
{
lpSem = NULL; //已经被释放!
}
}
UnlockIRQRestore( &uiSave );
#ifdef __DEBUG
if( lpSem == NULL )
{
WARNMSG( DEBUG_GetSemaphoreAndLock, ( "GetSemaphoreAndLock been released or invalid handle!.\r\n" ) );
}
#endif
return lpSem;
}
// ********************************************************************
// 声明:LPSEMAPHORE ReleaseSemaphoreAndUnlock( HANDLE hSem, UINT uObjType )
// 参数:
// IN hSem - 信号量句柄
// IN uObjType - 对象类型
// 返回值:
// 信号量对象指针
// 功能描述:
// 得到信号量句柄对应的指针并且锁住它
// 引用:
//
// ********************************************************************
#define DEBUG_ReleaseSemaphoreAndUnlock 0
VOID ReleaseSemaphoreAndUnlock( LPSEMAPHORE lpSem )
{
UINT uiSave;
LockIRQSave( &uiSave );
if( lpSem )
{
ASSERT( lpSem->nRefCount > 0 );
if( lpSem->nRefCount == 1 )
{
lpSem->nRefCount = 0;
UnlockIRQRestore( &uiSave );
_SemaphoreDelete( lpSem );
WARNMSG( DEBUG_ReleaseSemaphoreAndUnlock, ( "ReleaseSemaphoreAndUnlock: not free semaphore.\r\n" ) );
return;
}
else
{
lpSem->nRefCount--;
DEBUGMSG( DEBUG_ReleaseSemaphoreAndUnlock, ( "ReleaseSemaphoreAndUnlock: refcount(%d)!.\r\n",lpSem->nRefCount ) );
}
}
else
{
ERRORMSG( DEBUG_ReleaseSemaphoreAndUnlock, ( "ReleaseSemaphoreAndUnlock: not know error!.\r\n" ) );
}
UnlockIRQRestore( &uiSave );
}
// ********************************************************************
// 声明:DWORD WINAPI KL_WaitForSingleObject( HANDLE handle, DWORD dwMilliseconds )
// 参数:
// IN handle - 对象句柄
// IN dwMilliseconds - 等待时间,假如为INFINITE则为死等
// 返回值:
// WAIT_OBJECT_0 - 等待的对象有信号
// WAIT_TIMEOUT - 等待的对象无信号,超时退出
// WAIT_FAILED - 错误退出
// 功能描述:
// 等待一个对象直到其有信号或超时
// 引用:
// 系统API
// ********************************************************************
#define DEBUG_KL_WaitForSingleObject 0
DWORD WINAPI KL_WaitForSingleObject( HANDLE handle, DWORD dwMilliseconds )
{
UINT objType;
DWORD dwRetv = WAIT_FAILED;
LPSEMAPHORE lpho;
if( handle == CURRENT_THREAD_HANDLE ||
handle == CURRENT_PROCESS_HANDLE )
goto _error;
objType = GetHandleObjType( handle ); //得到对象类型
if( objType == OBJ_PROCESS )
{
LPPROCESS lpProcess = (LPPROCESS)HandleToPtr( handle, OBJ_PROCESS );
if( lpProcess )
{ //主进程
handle = lpProcess->lpMainThread->hThread;
objType = OBJ_THREAD;
}
else
{
goto _error;
}
}
switch( objType )
{
case OBJ_EVENT:
case OBJ_SEMAPHORE:
case OBJ_MUTEX:
{
lpho = GetSemaphoreAndLock( handle, objType );//HandleToPtr( handle, objType );//由句柄得到对象指针
if( lpho )
{
//*lppSem = lpho;
// 进入原子操作
dwRetv = DownSemphores( &lpho, 1, dwMilliseconds, TRUE );
ReleaseSemaphoreAndUnlock( lpho );
}
}
break;
case OBJ_THREAD:
{
LPTHREAD lpThread = (LPTHREAD)HandleToPtr( handle, OBJ_THREAD );
if( lpThread )
{
lpho = GetThreadSemp( lpThread ); //得到线程的退出信号对象
lpho = GetSemaphoreAndLock( lpho, 0 );
if( lpho )
{
//*lppSem = lpho;
// 原子操作
dwRetv = DownSemphores( &lpho, 1, dwMilliseconds, TRUE );
ReleaseSemaphoreAndUnlock( lpho );
}
}
else
dwRetv = WAIT_OBJECT_0;
}
break;
default:
ASSERT_NOTIFY( 0, "Invalid semaphore handle.\r\n" );
}
_error:
KL_SetLastError( ERROR_INVALID_PARAMETER );
return dwRetv;
}
// ********************************************************************
// 声明:DWORD WINAPI KL_WaitForMultipleObjects(
// DWORD nCount,
// CONST HANDLE *lpHandles,
// BOOL fWaitAll,
// DWORD dwMilliseconds )
// 参数:
// IN nCount - 信号对象的数量
// IN lpHandles - 保存有信号对象的句柄数组
// IN fWaitAll - 是否等待所有对象有信号才返回
// IN dwMilliseconds - 是否用超时返回功能,当值为INFINITE,表示没有超时功能;
// 否则,当等待时间达到dwMilliseconds所标定的值但仍没有信号产生时,
// 该函数将退出并返回WAIT_TIMEOUT
// 返回值:
// 返回WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount –1) 标示那一个对象有信号;
// 返回WAIT_TIMEOUT - 说明一个超时返回,当dwMilliseconds有效时才会返回该值
// 返回WAIT_FAILED - 系统产生一个错误
// 功能描述:
// 根据条件,等待一个或多个对象直到它们有信号或超时
// 引用:
//
// ********************************************************************
DWORD WINAPI KL_WaitForMultipleObjects(
DWORD nCount,
CONST HANDLE *lpHandles,
BOOL fWaitAll,
DWORD dwMilliseconds )
{
DWORD i = 0;
DWORD dwRetv = WAIT_FAILED;
// UINT uiSave;
LPSEMAPHORE lppSem[MAX_WAITOBJS]; //最大32个
if( nCount > MAX_WAITOBJS )
{ //参数无效
KL_SetLastError( ERROR_INVALID_PARAMETER );
return WAIT_FAILED;
}
//每个信号量指针指向对应的信号量
for( i = 0; i < nCount; i++ )
{
UINT objType;
if( lpHandles[i] == CURRENT_THREAD_HANDLE ||
lpHandles[i] == CURRENT_PROCESS_HANDLE )
break;
objType = GetHandleObjType( lpHandles[i] );
if( objType == OBJ_EVENT ||
objType == OBJ_SEMAPHORE ||
objType == OBJ_MUTEX )
{
if( ( lppSem[i] = GetSemaphoreAndLock( lpHandles[i], objType ) ) == NULL )
break;
}
else if( objType == OBJ_THREAD || objType == OBJ_PROCESS )
{
LPTHREAD lpThread;
HANDLE h = lpHandles[i];
if( objType == OBJ_PROCESS )
{
LPPROCESS lpProcess;
lpProcess = HandleToPtr( h, OBJ_PROCESS );
if( lpProcess )
h = lpProcess->lpMainThread->hThread;
else
h = 0;
}
lpThread = (LPTHREAD)HandleToPtr( h, OBJ_THREAD );
if( lpThread )
{
LPSEMAPHORE lpSem;
if( ( lpSem = GetThreadSemp( lpThread ) ) == NULL )
{ //无效
break;
}
//是否锁住?
if( (lppSem[i] = GetSemaphoreAndLock( lpSem, 0 )) == NULL )
break;
}
else
{ // thread 已经死掉
if( fWaitAll == FALSE || nCount == 1 )
{
dwRetv = WAIT_OBJECT_0 + i;
break;
}
else
{ //失败
break;// 将来增加
}
}
}
else
break;
}
//
if( i == nCount )
{ // 所有对象有效,进入原子操作
dwRetv = DownSemphores( lppSem, nCount, dwMilliseconds, fWaitAll );
}
else
{
RETAILMSG( 1, ( "WaitForMultipleObjects error: not all wait objects are valid.\r\n" ) );
}
//清除
nCount = i;
for( i = 0; i < nCount; i++ )
{
ReleaseSemaphoreAndUnlock( lppSem[i] );
}
return dwRetv;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -