📄 semaphor.c
字号:
// IN lpName-以字符串表示的对象名
// 返回值:
// 成功:返回信号量句柄
// 否则:返回NULL
// 功能描述:
// 创建一个信号量
// 引用:
//
// ********************************************************************
HANDLE WINAPI KL_CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //
int nInitialCount, // initial count
int nMaximumCount, // maximum count
LPCTSTR lpName //
)
{
return _CreateHandleObj( lpSemaphoreAttributes, nInitialCount, nMaximumCount, lpName, SF_SEMAPHORE, OBJ_SEMAPHORE, GetAPICallerProcessPtr() );
}
// ********************************************************************
// 声明:BOOL WINAPI KL_ReleaseSemaphore(
// HANDLE hSemaphore,
// int lReleaseCount, //
// LPINT lpPreviousCount //
// )
// 参数:
// IN hSemaphore-信号量句柄
// IN lReleaseCount-释放计数
// OUT lpPreviousCount-用于接受前次信号量计数
// 返回值:
// 成功:返回非零
// 否则:返回0
// 功能描述:
// 释放信号,假如有线程在等待该信号量则释放这些线程
// 引用:
// 系统API
// ********************************************************************
BOOL WINAPI KL_ReleaseSemaphore(
HANDLE hSemaphore,
int lReleaseCount, //
LPINT lpPreviousCount //
)
{
LPSEMAPHORE lpho = HandleToPtr( hSemaphore, OBJ_SEMAPHORE ); // 由句柄得到对象指针
if( lpPreviousCount )
*lpPreviousCount = 0;
if( lpho )
{
return _SemaphoreRelease( lpho, lReleaseCount, lpPreviousCount );
}
return FALSE;
}
// ********************************************************************
// 声明:BOOL FASTCALL Semaphore_Close( HANDLE hSemaphore )
// 参数:
// IN hSemaphore - 信号量句柄
// 返回值:
// 假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
// 删除信号量句柄及对象
// 引用:
// 被CloseHandle调用
// ********************************************************************
BOOL FASTCALL Semaphore_Close( HANDLE hSemaphore )
{
return _CloseSemaphoreObj( hSemaphore, OBJ_SEMAPHORE );
}
// ********************************************************************
// 声明:HANDLE WINAPI KL_CreateMutex(
// LPSECURITY_ATTRIBUTES lpMutexAttributes, // must is 0
// BOOL bInitialOwner, // flag for initial ownership
// LPCTSTR lpName // must is 0
// )
// 参数:
// IN lpMutexAttributes - 安全属性(必须为NULL)
// IN bInitialOwner - 是否创建时就拥有该互斥量
// IN lpName - 互斥量名(可以为NULL)
// 返回值:
// 假如成功,返回互斥量句柄; 否则返回NULL
// 功能描述:
// 创建互斥量, 如果lpName不为NULL,则创建一个命名互斥量,其它进程可以用同名调用该函数得到对该互斥量的跨进程引用
// 如果是命名互斥量并且多个进程会用到它,应该使bInitialOwner为FALSE。拥有互斥量的线程可以多次调用等待功能而不会
// 被锁住,这时,你应该调用同样多次释放功能(ReleaseMutex)。
// 互斥量只能被一个线程所拥有
// 用CloseHandle去删除互斥量
// 引用:
// 系统API
// ********************************************************************
HANDLE WINAPI KL_CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // must is 0
BOOL bInitialOwner, // flag for initial ownership
LPCTSTR lpName // must is 0
)
{
return _CreateHandleObj( lpMutexAttributes, bInitialOwner ? 0 : 1, 1, lpName, SF_MUTEX | SF_OWNER, OBJ_MUTEX, GetAPICallerProcessPtr() );
}
// ********************************************************************
// 声明:BOOL WINAPI KL_ReleaseMutex( HANDLE hMutex )
// 参数:
// IN hMutex - 互斥量句柄
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 释放对互斥量的拥有权并使互斥量对象有信号。只有拥有该互斥量的线程才能释放它
// 引用:
// 系统API
// ********************************************************************
BOOL WINAPI KL_ReleaseMutex( HANDLE hMutex )
{
LPSEMAPHORE lpho = HandleToPtr( hMutex, OBJ_MUTEX ); //由句柄得到对象指针
if( lpho ) //有效吗?
{ //是
if( lpho->lpOwner == lpCurThread ) //是否当前线程拥有该互斥量
{ //是
if( lpho->nLockCount == 1 ) //当前线程重复等待该互斥量的次数是否为 1
return _SemaphoreRelease( lpho, 1, 0 ); // 是,释放它
else
{
lpho->nLockCount--; //否,仅仅减去重复计数
return TRUE;
}
}
}
return FALSE;
}
// ********************************************************************
// 声明:HANDLE WINAPI KL_CreateEvent(
// LPSECURITY_ATTRIBUTES lpEventAttributes, // must is NULL
// BOOL bManualReset,
// BOOL bInitialState,
// LPTSTR lpName )
// 参数:
// IN lpEventAttributes - 安全属性
// IN bManualReset - 是否手工重设信号
// IN bInitialState - 事件的状态,假如为TRUE,事件创建后为有信号状态
// IN lpName - 事件名(可以为NULL)
// 返回值:
// 假如成功,返回有效的句柄值;否则,返回NULL
// 功能描述:
// 创建事件对象。假如lpName不为NULL,则创建一个其它进程可以访问的命名事件。
// 如果为命名事件且之前已经创建了该事件,则忽略bManualReset和bInitialState
// 如果bManualReset为FALSE,则当事件有信号并且有线程等待该事件,则系统释放等
// 待线程并且自动将该事件重新设为无信号状态
// 引用:
// 系统API
// ********************************************************************
HANDLE WINAPI KL_CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // must is NULL
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName )
{
UINT uiFlag;
HANDLE h;
if( bManualReset )
uiFlag = SF_MANUALRESET;
else
uiFlag = 0;
h = _CreateHandleObj( lpEventAttributes, bInitialState ? 1 : 0, 1, lpName, SF_EVENT | uiFlag , OBJ_EVENT, GetAPICallerProcessPtr() );
if( h && bInitialState )
{
LPVOID lpho = HandleToPtr( h, OBJ_EVENT );//由句柄得到对象指针
_SemaphoreRelease( (LPSEMAPHORE)lpho, 1, NULL );
}
return h;
}
// ********************************************************************
// 声明:BOOL WINAPI KL_ResetEvent( HANDLE hEvent )
// 参数:
// IN hEvent - 事件句柄
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 将事件对象设为无信号状态
// 引用:
// 系统API
// ********************************************************************
BOOL WINAPI KL_ResetEvent( HANDLE hEvent )
{
LPVOID lpho = HandleToPtr( hEvent, OBJ_EVENT ); //由句柄得到对象指针
if( lpho )//
{ // 有效的指针
return _SemaphoreReset( (LPSEMAPHORE)lpho );//
}
return FALSE;
}
// ********************************************************************
// 声明:BOOL WINAPI KL_SetEvent( HANDLE hEvent )
// 参数:
// IN hEvent - 事件对象句柄
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 设置事件为信号状态,如果有等待的线程,则释放它们。
// 线程通过等待功能检查事件信号,当线程得到信号后,对信号的处理为下:
// 当该事件为手工重设功能,该事件的信号不会改变直到调用了ResetEvent,
// 当该事件为非手工重设功能,该信号重设为无信号。
// 仅仅只有一个等待的线程能得到信号
// 引用:
// 系统API
// ********************************************************************
BOOL WINAPI KL_SetEvent( HANDLE hEvent )
{
LPVOID lpho = HandleToPtr( hEvent, OBJ_EVENT );//由句柄得到对象指针
if( lpho )
{
return _SemaphoreRelease( (LPSEMAPHORE)lpho, 1, NULL );
}
return FALSE;
}
// ********************************************************************
// 声明:BOOL WINAPI KL_PulseEvent( HANDLE hEvent )
// 参数:
// IN hEvent - 事件对象句柄
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 设置事件为信号状态,如果有等待的线程,则释放它们。
// 线程通过等待功能检查事件信号,当线程得到信号后,对信号的处理为下:
// 当该事件为手工重设功能,该信号重设为无信号,
// 当该事件为非手工重设功能,该信号重设为无信号。
// 当该事件为手工重设功能,当前等待的所有线程能得到信号并被释放
// 当该事件为非手工重设功能,仅仅一个线程能得到信号
// 引用:
//
// ********************************************************************
BOOL WINAPI KL_PulseEvent( HANDLE hEvent )
{
LPSEMAPHORE lpho = (LPSEMAPHORE)HandleToPtr( hEvent, OBJ_EVENT );//由句柄得到对象指针
if( lpho )
{
if( lpho->semFlag & SF_MANUALRESET )
{
UINT uiSave;
LockIRQSave( &uiSave );
if(lpho->lpWaitQueue)
{
LPWAITQUEUE lpWaitHead = WAIT_QUEUE_HEAD( &lpho->lpWaitQueue );
LPWAITQUEUE lpWaitQueue = lpho->lpWaitQueue;
while( lpWaitQueue != lpWaitHead )
{
lpWaitQueue->lpThread->flag |= FLAG_PULSE_EVENTING;
lpWaitQueue = lpWaitQueue->lpNext;
}
}
UnlockIRQRestore( &uiSave );
}
if( _SemaphoreRelease( (LPSEMAPHORE)lpho, 1, NULL ) )
{
if( lpho->semFlag & SF_MANUALRESET )
{
return _SemaphoreReset( (LPSEMAPHORE)lpho );
}
}
}
return FALSE;
}
// ********************************************************************
// 声明:BOOL FASTCALL Event_Close( HANDLE hEvent )
// 参数:
// IN hEvent - 事件对象句柄
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 当系统调用CloseHandle时,如果句柄对象为事件对象,CloseHandle则会调用该函数
// 引用:
// hmgr.c
// ********************************************************************
BOOL FASTCALL Event_Close( HANDLE hEvent )
{
return _CloseSemaphoreObj( hEvent, OBJ_EVENT );
}
// ********************************************************************
// 声明:BOOL FASTCALL Mutex_Close( HANDLE hMutex )
// 参数:
// IN hEvent - 事件对象句柄
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 当系统调用CloseHandle时,如果句柄对象为Mutex对象,CloseHandle则会调用该函数
// 引用:
// hmgr.c
// ********************************************************************
BOOL FASTCALL Mutex_Close( HANDLE hMutex )
{
return _CloseSemaphoreObj( hMutex, OBJ_MUTEX );
}
// ********************************************************************
// 声明:VOID WINAPI KL_InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
// IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
// 无
// 功能描述:
// 创建并初始化一个冲突段对象
// 引用:
// 系统API
// ********************************************************************
VOID WINAPI KL_InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
if( lpCriticalSection )
{
memset( lpCriticalSection, 0, sizeof( CRITICAL_SECTION ) );
lpCriticalSection->dwOwnerThreadId = -1;
lpCriticalSection->hSemaphore = _CreateHandleObj( NULL, 1, 1, NULL, SF_SEMAPHORE, OBJ_SEMAPHORE, GetAPICallerProcessPtr() );//KL_CreateMutex( 0, 0, NULL );//lpCriticalSection->lpcsName );
//ASSERT( lpCriticalSection->hSemaphore );
}
else
{
ERRORMSG( 1 , ( "KL_InitializeCriticalSection error: null ptr,pc=0x%x,proc=%s.\r\n", lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->lpCurProcess->lpszApplicationName ) );
}
}
// ********************************************************************
// 声明:VOID FASTCALL KC_InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
// IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
// 无
// 功能描述:
// 创建并初始化一个冲突段对象
// 引用:
// 内部调用
// ********************************************************************
// use by kernel
#define CSF_KERNEL 0x80000000
#define CSF_DEBUG 0x00000001
VOID FASTCALL KC_InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
memset( lpCriticalSection, 0, sizeof( CRITICAL_SECTION ) );
lpCriticalSection->dwOwnerThreadId = -1;
lpCriticalSection->hSemaphore = _SemaphoreCreate( NULL, 1, 1, NULL, SF_SEMAPHORE );
//ASSERT( lpCriticalSection->hSemaphore );
lpCriticalSection->uiFlag = CSF_KERNEL;
}
// ********************************************************************
// 声明:VOID WINAPI KL_DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
// IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
// 无
// 功能描述:
// 与KL_InitializeCriticalSection相反,该功能删除冲突段对象
// 引用:
//
// ********************************************************************
VOID WINAPI KL_DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
if( lpCriticalSection )
{
if( lpCriticalSection->uiFlag & CSF_KERNEL )
{
_CloseSemaphoreObj( lpCriticalSection->hSemaphore, 0 );
}
else
KL_CloseHandle( lpCriticalSection->hSemaphore );
lpCriticalSection->hSemaphore = NULL;
if( lpCriticalSection->uiFlag & CSF_DEBUG )
{
RETAILMSG( 1, ( "DeleteCriticalSection:lpcs=0x%x,lpcsName=%s.\r\n", lpCriticalSection, lpCriticalSection->lpcsName ) );
}
}
else
{
ERRORMSG( 1 , ( "KL_DeleteCriticalSection error: null ptr,pc=0x%x,proc=%s.\r\n", lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->lpCurProcess->lpszApplicationName ) );
DumpCallStack( lpCurThread );
}
}
// ********************************************************************
// 声明:VOID WINAPI KL_LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
// IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
// 无
// 功能描述:
// 离开冲突段
// 引用:
// 系统API
// ********************************************************************
VOID WINAPI KL_LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
if( lpCriticalSection )
{
if( lpCriticalSection->dwOwnerThreadId == lpCurThread->dwThreadId ) //当前线程拥有该冲突段吗?
{ //是
#ifdef __DEBUG
if( lpCriticalSection->uiFlag & CSF_DEBUG ) //是否输出调试信息
{ //是
RETAILMSG( 1, ( "LeaveCriticalSection:lpcs=0x%x,lpcsName=%s,iLockCount=%d.\r\n", lpCriticalSection, lpCriticalSection->lpcsName, lpCriticalSection->iLockCount ) );
}
#endif
if( lpCriticalSection->iLockCount != 1 ) // 最后一次离开吗 ?
lpCriticalSection->iLockCount--; // 不是,简单的将进入数减一(同一个线程能多次进入冲突段)
else
{ // 是最后一次离开
LPSEMAPHORE lpho;
#ifdef DEBUG_CRITSEC
if( lpCriticalSection->lpcsName )
{
DWORD dwCurThreadId = KL_GetCurrentThreadId();
RETAILMSG( 1, ( "upcs=%s, cid=0x%x, oid=0x%x, count=%d\r\n", lpCriticalSection->lpcsName, dwCurThreadId, lpCriticalSection->dwOwnerThreadId, lpCriticalSection->iLockCount ) );
}
#endif //DEBUG_CRITSEC
//
lpCriticalSection->dwOwnerThreadId |= 1; // 阻止所有的线程操作该对象 mask all threads with the crit
if( lpCriticalSection->uiFlag & CSF_KERNEL ) //是否是内核自己的创建的
lpho = (LPSEMAPHORE)lpCriticalSection->hSemaphore; // 是
else
lpho = HandleToPtr( lpCriticalSection->hSemaphore, -1 ); // 用户对象
if( lpho )
UpCrit( lpho, lpCriticalSection ); //进入原子操作
}
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -