?? synobj.cpp
字號:
if(NULL == lpEvent) //Parameter check.
return OBJECT_WAIT_FAILED;
if(0 == dwTimeOut) //Call this routine with out time out.
return WaitForEventObject(lpObject);
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(EVENT_STATUS_FREE == lpEvent->dwEventStatus) //Resides signal status.
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return OBJECT_WAIT_RESOURCE;
}
//
//The event object is not in signal status,so we must wait it.
//
lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
lpParam = (__EVENT_CALLBACK_PARAM*)KMemAlloc(
sizeof(__EVENT_CALLBACK_PARAM),
KMEM_SIZE_TYPE_ANY); //Allocate memory for call back parameter.
if(NULL == lpParam) //Can not allocate memory.
{
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
PrintLine("ERROR : Can not allocate memory,in WaitForEventObjectEx routine.");
return OBJECT_WAIT_FAILED;
}
lpParam->dwWakeupReason = OBJECT_WAIT_RESOURCE;
lpParam->lpEvent = lpEvent;
lpParam->lpKernelThread = lpKernelThread;
lpTimerObject = (__TIMER_OBJECT*)System.SetTimer((__COMMON_OBJECT*)&System,
lpKernelThread,
#define EVENT_TIMER_ID 0x00000100
EVENT_TIMER_ID,
dwTimeOut,
EventCallback,
lpParam,
TIMER_FLAGS_ONCE);
if(NULL == lpTimerObject) //Failed to set timer.
{
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KMemFree((LPVOID)lpParam,KMEM_SIZE_TYPE_ANY,0L);
PrintLine("ERROR : Can not set timer,in WaitForEventObjectEx routine.");
return OBJECT_WAIT_FAILED;
}
//
//Now,we should insert the current kernel thread into waiting queue of
//event object.
//
lpEvent->lpWaitingQueue->InsertIntoQueue((__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread,
0L);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KernelThreadManager.ScheduleFromProc(&lpKernelThread->KernelThreadContext);
//
//The following code will be executed when the current kernel thread be waken up
//again.
//
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
switch(lpParam->dwWakeupReason)
{
case OBJECT_WAIT_RESOURCE: //The kernel thread is waken up for having resource.
System.CancelTimer((__COMMON_OBJECT*)&System,
(__COMMON_OBJECT*)lpTimerObject);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KMemFree((LPVOID)lpParam,KMEM_SIZE_TYPE_ANY,0L);
return OBJECT_WAIT_RESOURCE;
case OBJECT_WAIT_TIMEOUT:
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KMemFree((LPVOID)lpParam,KMEM_SIZE_TYPE_ANY,0L);
return OBJECT_WAIT_TIMEOUT;
default:
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KMemFree((LPVOID)lpParam,KMEM_SIZE_TYPE_ANY,0L);
PrintLine("Exeception : In WaitForEventObjectEx routine.");
return OBJECT_WAIT_FAILED;
}
return OBJECT_WAIT_FAILED; //Should not reach here.
}
//
//One kernel thread can use the following steps to create an event object:
// 1. Create an event object by calling CreateObject;
// 2. Initialize the event object by calling the event object's initialize routine;
// 3. Set the event object's initializing status by calling SetEvent or ResetEvent.
//In order to make this easy,we define a wrap routine,CreatEvent,to wrap these steps
//as one step.
//
__COMMON_OBJECT* CreateEvent(BOOL bInitialState,LPVOID lpReserved)
{
__COMMON_OBJECT* lpCommonObject = NULL;
__EVENT* lpEvent = NULL;
DWORD dwInitialState = 0L;
lpCommonObject = ObjectManager.CreateObject(&ObjectManager,
NULL,
OBJECT_TYPE_EVENT);
if(NULL == lpCommonObject)
goto __TERMINAL;
if(!lpCommonObject->Initialize(lpCommonObject))
{
ObjectManager.DestroyObject(&ObjectManager,lpCommonObject);
lpCommonObject = NULL;
goto __TERMINAL;
}
lpEvent = (__EVENT*)lpCommonObject;
if(bInitialState)
lpEvent->SetEvent((__COMMON_OBJECT*)lpEvent);
__TERMINAL:
return lpCommonObject;
}
VOID DestroyEvent(__COMMON_OBJECT* lpThis)
{
ObjectManager.DestroyObject(&ObjectManager,lpThis);
}
////////////////////////////////////////////////////////////////////////////////////
//
// ------------------ ** The implementation of MUTEX object ** ---------------------
//
///////////////////////////////////////////////////////////////////////////////////
//
//The implementation of ReleaseMutex.
//
static DWORD ReleaseMutex(__COMMON_OBJECT* lpThis)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__MUTEX* lpMutex = NULL;
DWORD dwPreviousStatus = 0L;
DWORD dwFlags = 0L;
if(NULL == lpThis) //Parameter check.
return 0L;
lpMutex = (__MUTEX*)lpThis;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(lpMutex->dwWaitingNum > 0) //If there are other kernel threads waiting for this object.
lpMutex->dwWaitingNum --; //Decrement the counter.
if(0 == lpMutex->dwWaitingNum) //There is not kernel thread waiting for the object.
{
dwPreviousStatus = lpMutex->dwMutexStatus;
lpMutex->dwMutexStatus = MUTEX_STATUS_FREE; //Set to free.
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return 0L;
}
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpMutex->lpWaitingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpMutex->lpWaitingQueue,
0L); //Get one waiting kernel thread to run.
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
KernelThreadManager.lpReadyQueue->InsertIntoQueue(
(__COMMON_OBJECT*)KernelThreadManager.lpReadyQueue,
(__COMMON_OBJECT*)lpKernelThread,
lpKernelThread->dwScheduleCounter); //Put the kernel thread to ready queue.
return dwPreviousStatus;
}
//
//The implementation of WaitForMutexObject.
//
static DWORD WaitForMutexObject(__COMMON_OBJECT* lpThis)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__MUTEX* lpMutex = NULL;
DWORD dwFlags = 0L;
if(NULL == lpThis) //Parameter check.
return 0L;
lpMutex = (__MUTEX*)lpThis;
if(MUTEX_STATUS_FREE == lpMutex->dwMutexStatus) //If the current mutex is free.
{
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpMutex->dwMutexStatus = MUTEX_STATUS_OCCUPIED; //Modify the current status.
lpMutex->dwWaitingNum ++; //Increment the counter.
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return 1L; //The current kernel thread successfully occupy
//the mutex.
}
else //The status of the mutex is occupied.
{
lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
lpMutex->dwWaitingNum ++; //Increment the waiting number.
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
lpMutex->lpWaitingQueue->InsertIntoQueue(
(__COMMON_OBJECT*)lpMutex->lpWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread,
0L);
//Reschedule all kernel thread(s).
KernelThreadManager.ScheduleFromProc(&lpKernelThread->KernelThreadContext);
}
return 0L;
}
//
//The implementation of MutexInitialize.
//
BOOL MutexInitialize(__COMMON_OBJECT* lpThis)
{
__MUTEX* lpMutex = NULL;
__PRIORITY_QUEUE* lpQueue = NULL;
BOOL bResult = FALSE;
if(NULL == lpThis) //Parameter check.
return bResult;
lpQueue = (__PRIORITY_QUEUE*)ObjectManager.CreateObject(&ObjectManager,
NULL,
OBJECT_TYPE_PRIORITY_QUEUE);
if(NULL == lpQueue) //Failed to create priority queue.
return bResult;
if(!lpQueue->Initialize((__COMMON_OBJECT*)lpQueue)) //Initialize the queue object.
goto __TERMINAL;
lpMutex = (__MUTEX*)lpThis;
lpMutex->dwMutexStatus = MUTEX_STATUS_FREE;
lpMutex->lpWaitingQueue = lpQueue;
lpMutex->WaitForThisObject = WaitForMutexObject;
lpMutex->dwWaitingNum = 0L;
lpMutex->ReleaseMutex = ReleaseMutex;
bResult = TRUE; //Successful to initialize the mutex object.
__TERMINAL:
if(!bResult)
{
if(NULL != lpQueue) //Release the queue object.
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpQueue);
}
return bResult;
}
//
//The implementation of MutexUninitialize.
//
VOID MutexUninitialize(__COMMON_OBJECT* lpThis)
{
__MUTEX* lpMutex = NULL;
__PRIORITY_QUEUE* lpWaitingQueue = NULL;
if(NULL == lpThis) //parameter check.
return;
lpWaitingQueue = ((__MUTEX*)lpThis)->lpWaitingQueue;
if(NULL != lpWaitingQueue)
{
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpWaitingQueue);
}
return;
}
//
//The implementation of CreateMutex.
//
__COMMON_OBJECT* CreateMutex(LPVOID lpReserved)
{
return NULL;
}
//
//The implementation of DestroyMutex.
//
VOID DestroyMutex(__COMMON_OBJECT* lpThis)
{
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -