?? synobj.cpp
字號(hào):
//***********************************************************************/
// Author : Garry
// Original Date : Sep 21, 2005
// Module Name : SYNOBJ.CPP
// Module Funciton :
// This module countains synchronization object's implementation
// code.
// The following synchronization object(s) is(are) defined
// in this file:
// 1. EVENT
// 2. MUTEX
// 3. SEMAPHORE
// 4. TIMER
//
// ************
// This file is the most important file of Hello China.
// ************
// Last modified Author :
// Last modified Date :
// Last modified Content :
// 1.
// 2.
// Lines number :
//***********************************************************************/
#ifndef __STDAFX_H__
#include "StdAfx.h"
#endif
//
//Routines pre-declaration.
//
static DWORD WaitForEventObject(__COMMON_OBJECT*);
static DWORD SetEvent(__COMMON_OBJECT*);
static DWORD ResetEvent(__COMMON_OBJECT*);
static DWORD WaitForEventObjectEx(__COMMON_OBJECT*,DWORD);
//---------------------------------------------------------------------------------
//
// SYNCHRONIZATION OBJECTS
//
//----------------------------------------------------------------------------------
//
//Event object's initializing routine.
//This routine initializes the members of an event object.
//
BOOL EventInitialize(__COMMON_OBJECT* lpThis)
{
BOOL bResult = FALSE;
__EVENT* lpEvent = NULL;
__PRIORITY_QUEUE* lpPriorityQueue = NULL;
if(NULL == lpThis)
goto __TERMINAL;
lpEvent = (__EVENT*)lpThis;
lpPriorityQueue = (__PRIORITY_QUEUE*)
ObjectManager.CreateObject(&ObjectManager,NULL,
OBJECT_TYPE_PRIORITY_QUEUE);
if(NULL == lpPriorityQueue)
goto __TERMINAL;
bResult = lpPriorityQueue->Initialize((__COMMON_OBJECT*)lpPriorityQueue);
if(!bResult)
goto __TERMINAL;
lpEvent->lpWaitingQueue = lpPriorityQueue;
lpEvent->dwEventStatus = EVENT_STATUS_OCCUPIED;
lpEvent->SetEvent = SetEvent;
lpEvent->ResetEvent = ResetEvent;
lpEvent->WaitForThisObjectEx = WaitForEventObjectEx;
lpEvent->WaitForThisObject = WaitForEventObject;
bResult = TRUE;
__TERMINAL:
if(!bResult)
{
if(NULL != lpPriorityQueue) //Release the priority queue.
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpPriorityQueue);
}
return bResult;
}
//
//Event object's uninitializing routine.
//This routine calles priority queue's uninitialize routine to release
//priority queue's resource.
//
VOID EventUninitialize(__COMMON_OBJECT* lpThis)
{
__EVENT* lpEvent = NULL;
__PRIORITY_QUEUE* lpPriorityQueue = NULL;
if(NULL == lpThis)
return;
lpEvent = (__EVENT*)lpThis;
lpPriorityQueue = lpEvent->lpWaitingQueue;
if(NULL != lpPriorityQueue)
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpPriorityQueue); //*******CAUTION!!!************
//lpPriorityQueue->Uninitialize((__COMMON_OBJECT*)lpPriorityQueue);
return;
}
//
//The implementation of SetEvent.
//This routine do the following:
// 1. Saves the previous status into a local variable;
// 2. Sets the current status of the event to EVENT_STATUS_FREE;
// 3. Wakes up all kernel thread(s) in it's waiting queue.
// 4. Returns the previous status.
//
static DWORD SetEvent(__COMMON_OBJECT* lpThis)
{
DWORD dwPreviousStatus = EVENT_STATUS_OCCUPIED;
__EVENT* lpEvent = NULL;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags = 0L;
if(NULL == lpThis)
return dwPreviousStatus;
lpEvent = (__EVENT*)lpThis;
dwPreviousStatus = lpEvent->dwEventStatus;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpEvent->dwEventStatus = EVENT_STATUS_FREE; //Set the current status to free.
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
lpKernelThread = (__KERNEL_THREAD_OBJECT*)
lpEvent->lpWaitingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
NULL);
while(lpKernelThread) //Remove all kernel thread(s) from
//waiting queue,and insert them into
//ready queue of kernel thread,so,they
//would be scheduled in appropriate
//time.
{
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
KernelThreadManager.lpReadyQueue->InsertIntoQueue(
(__COMMON_OBJECT*)KernelThreadManager.lpReadyQueue,
(__COMMON_OBJECT*)lpKernelThread,
lpKernelThread->dwScheduleCounter
);
lpKernelThread = (__KERNEL_THREAD_OBJECT*)
lpEvent->lpWaitingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
NULL);
}
return dwPreviousStatus;
}
//
//The implementation of ResetEvent.
//
static DWORD ResetEvent(__COMMON_OBJECT* lpThis)
{
__EVENT* lpEvent = NULL;
DWORD dwPreviousStatus = 0L;
DWORD dwFlags = 0L;
if(NULL == lpThis)
return dwPreviousStatus;
lpEvent = (__EVENT*)lpThis;
dwPreviousStatus = lpEvent->dwEventStatus;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpEvent->dwEventStatus = EVENT_STATUS_OCCUPIED;
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return dwPreviousStatus;
}
//
//The implementation of WaitForEventObject.
//
static DWORD WaitForEventObject(__COMMON_OBJECT* lpThis)
{
__EVENT* lpEvent = NULL;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__KERNEL_THREAD_CONTEXT* lpContext = NULL;
DWORD dwFlags = 0L;
if(NULL == lpThis)
return OBJECT_WAIT_FAILED;
lpEvent = (__EVENT*)lpThis;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(EVENT_STATUS_FREE == lpEvent->dwEventStatus)
{
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return OBJECT_WAIT_RESOURCE;
}
else
{
lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
//ENTER_CRITICAL_SECTION();
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED; //Once the status of current
//kernel thread is set to
//BLOCKED,the thread will
//never be prompted by system
//until it gives up the CPU
//by itself,for detail information,
//please refer to the schedule
//routine.
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
lpEvent->lpWaitingQueue->InsertIntoQueue(
(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread,
0L);
lpContext = &lpKernelThread->KernelThreadContext;
//SwitchTo(lpContext);
KernelThreadManager.ScheduleFromProc(lpContext);
//__asm{ //-------- ** debug ** ------------
// mov eax,0x09099090
// mov ebx,0x09099090
//}
}
return OBJECT_WAIT_RESOURCE;
}
//
//In the following section we implements the time out waiting operation.
//
typedef struct{
__EVENT* lpEvent;
__KERNEL_THREAD_OBJECT* lpKernelThread;
DWORD dwWakeupReason;
}__EVENT_CALLBACK_PARAM; //A new type used to pass parameters to call back routine.
//
//The implementation of call back routine.
//This routine is called when timer set by WaitForThisObjectEx routine timeout.
//It does the following:
// 1. Try to delete the kernel thread object who calls WaitForThisObjectEx;
// 2. If successful,it means the kernel thread is not waken up yet,so this routine
// wakes up the kernel thread,set wakeup reason to OBJECT_WAIT_TIME,then return;
// 3. If delete failed,it means the kernel thread is waken up now,so it only returns.
//
static DWORD EventCallback(LPVOID lpParam1)
{
__EVENT_CALLBACK_PARAM* lpParam = (__EVENT_CALLBACK_PARAM*)lpParam1;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__EVENT* lpEvent = NULL;
if(NULL == lpParam) //Parameter validate.
return 0L;
lpKernelThread = lpParam->lpKernelThread;
lpEvent = lpParam->lpEvent;
if(!lpEvent->lpWaitingQueue->DeleteFromQueue( //Try to delete the kernel thread.
(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread)) //The kernel thread is waken up yet.
return 0L;
//
//Delete the kernel thread successfully,so must waken up the kernel thread.
//
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
KernelThreadManager.lpReadyQueue->InsertIntoQueue(
(__COMMON_OBJECT*)KernelThreadManager.lpReadyQueue,
(__COMMON_OBJECT*)lpKernelThread,
lpKernelThread->dwScheduleCounter); //Insert into ready queue.
lpParam->dwWakeupReason = OBJECT_WAIT_TIMEOUT;
return 1L;
}
//
//The implementation of WaitForEventObjectEx routine.
//This routine supports time out waiting,that can be used in network protocol's
//implementation.
//
static DWORD WaitForEventObjectEx(__COMMON_OBJECT* lpObject,DWORD dwTimeOut)
{
__EVENT* lpEvent = (__EVENT*)lpObject;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags = 0L;
__EVENT_CALLBACK_PARAM* lpParam = NULL;
__TIMER_OBJECT* lpTimerObject = NULL;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -