⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resmance.cpp

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 CPP
字号:
/***************************************************************************
 * Name        : resman.cpp
 * Title       : WinCE resource manager
 * Author(s)   : Imagination Technologies
 * Created	   : 19th June 2003
 *
 * Copyright   : 2003 by Imagination Technologies. All rights reserved.
 *             : No part of this software, either material or conceptual 
 *             : may be copied or distributed, transmitted, transcribed,
 *             : stored in a retrieval system or translated into any 
 *             : human or computer language in any form by any means,
 *             : electronic, mechanical, manual or other-wise, or 
 *             : disclosed to third parties without the express written
 *             : permission of Imagination Technologies Limited, Unit 8,
 *             : HomePark Industrial Estate, King's Langley, Hertfordshire,
 *             : WD4 8LZ, U.K.
 *
 * Description : Handles the WinCE specific side of resource management
 *
 * Platform    : WinCE
 *
 * Modifications:-
 * $Log: resmanCE.cpp $
 *
 ****************************************************************************/

#include	"precomp.h"

extern "C"
{
	#include	"drvescape.h"
}

/*****************************************************************************
 FUNCTION	: AmendProcessesInList
    
 PURPOSE	: Add or delete items for the process monitor handle list
 PARAMETERS	: RESMAN_MON_THREAD_PARAMS *pMonParams
			  HANDLE				hProcess	Handle to add/delete
			  IMG_BOOL				bAdd		True - add, False - delete
			  
 RETURNS	: True - successfully added or deleted handle
*****************************************************************************/

IMG_BOOL AmendProcessesInList(PRESMAN_MON_THREAD_PARAMS pMonParams, HANDLE hProcess, IMG_BOOL bAdd)
{
	IMG_UINT32 ProcessInxInList = (IMG_UINT32) -1;
	IMG_UINT32 ScanIndex;

	/* Attempt to find process handle in list, remember to skip first element */
	for(ScanIndex = 1; ScanIndex < MAXIMUM_WAIT_OBJECTS && pMonParams->hProcesses[ScanIndex]; ScanIndex++)
	{
		if(pMonParams->hProcesses[ScanIndex] == hProcess)
		{
			ProcessInxInList = ScanIndex;
			break;
		}
	}

	if(bAdd)
	{
		/******************************************************** Add handle */

		if(ProcessInxInList != (IMG_UINT32) -1) return(IMG_FALSE);	/* Handle already in list */
		if(ScanIndex == MAXIMUM_WAIT_OBJECTS)	return(IMG_FALSE);	/* List Full */

		/* Add to list, bump count */
		pMonParams->hProcesses[ScanIndex] = hProcess;
		pMonParams->ui32ProcessCnt++;
	}
	else
	{
		/***************************************************** Delete handle */

		if(ProcessInxInList == (IMG_UINT32) -1) return(IMG_FALSE);	/* Handle not in list */

		/* Remove item from list, ripple up list, ensure last item zero-ed */
		for(; ProcessInxInList < (MAXIMUM_WAIT_OBJECTS-1); ProcessInxInList++)
		{
			pMonParams->hProcesses[ProcessInxInList] = pMonParams->hProcesses[ProcessInxInList+1];
		}

		pMonParams->hProcesses[ProcessInxInList] = 0;

		pMonParams->ui32ProcessCnt--;
	}

	return(IMG_TRUE);
}

/*****************************************************************************
 FUNCTION	: MonitorProcesses
    
 PURPOSE	: Monitor  processoes
 PARAMETERS	: RESMAN_MON_THREAD_PARAMS *
			  
 RETURNS	: 
*****************************************************************************/

static ULONG MonitorThreadProc(PVOID pvParameter)
{
	PRESMAN_MON_THREAD_PARAMS	pMonParams = (PRESMAN_MON_THREAD_PARAMS) pvParameter;
	DWORD						dwWaitRtn;
	IMG_BOOL					bTerminateRequested = IMG_FALSE;

	while(!bTerminateRequested)
	{
		/* Wait for some thing to happen */
		dwWaitRtn = WaitForMultipleObjects(pMonParams->ui32ProcessCnt, 
										   pMonParams->hProcesses, 
										   FALSE, INFINITE);

		if(dwWaitRtn == WAIT_OBJECT_0)
		{
			/********************************************* Recieved command */
			/* WARNING this process loop is replicated in ResManSendCmd below */

			switch(pMonParams->eCommand)
			{
				case PMC_TERMINATE_THREAD:		
				{
					pMonParams->bCmdSuccessful	= IMG_TRUE;
					bTerminateRequested			= IMG_TRUE;
					break;
				}

				case PMC_REGISTER_PROCESS:
				{
					pMonParams->bCmdSuccessful = AmendProcessesInList(pMonParams, pMonParams->hCmdParam, IMG_TRUE);
					break;
				}

				case PMC_UNREGISTER_PROCESS:
				{
					pMonParams->bCmdSuccessful = AmendProcessesInList(pMonParams, pMonParams->hCmdParam, IMG_FALSE);
					break;
				}

				default:
				{
					pMonParams->bCmdSuccessful = IMG_FALSE;
					break;
				}
			}

			/* Signal command completion */
			if(pMonParams->eCommand != PMC_CMDRESET)
			{
				SetEvent(pMonParams->hCommandCompletion);
			}
		}
		else
		{
			/******************************************** Process terminated */

			HANDLE hTerminatedProcess = pMonParams->hProcesses[dwWaitRtn];

			/* Remove handle for list */
			AmendProcessesInList(pMonParams, hTerminatedProcess, IMG_FALSE);

			/* Send driver escape to signal termination, this will ensure
			   that the services are not re-entered by another thread */

			DRVESC_RESMAN_THREAD_TERMINATED_PARAMS	sResManThreadTerminated;

			sResManThreadTerminated.hProcess	= hTerminatedProcess;

			ExtEscape(GetWindowDC(NULL), DRVESC_RESMAN_THREAD_TERMINATED, 0, NULL,  
					  sizeof(sResManThreadTerminated), (LPSTR)&sResManThreadTerminated);
		}
	}

	return(0);
}

/*****************************************************************************
 FUNCTION	: ResManSendCommand
    
 PURPOSE	: Send a command to the resman thread
 PARAMETERS	: 
			  
 RETURNS	: 
*****************************************************************************/

IMG_BOOL MBX::ResManSendCommand(PMC eCommand, HANDLE hCmdParam)
{
	if(m_sMonitorThread.hThread == NULL) return(IMG_FALSE);

	/* Send command */
	m_sMonitorThread.eCommand		= eCommand;
	m_sMonitorThread.hCmdParam		= hCmdParam;
	m_sMonitorThread.bCmdSuccessful = IMG_FALSE;

	SetEvent(m_sMonitorThread.hProcesses[0]);

	/* Wait for ACK */
	if(WaitForSingleObject(m_sMonitorThread.hCommandCompletion, 1000) == WAIT_TIMEOUT)
	{
		/* Wait timeout will happen if the monitor thread is attempting to call the 
		   driver, via a driver escape, and we are waiting in the driver. Handle as
		   a special case */

		ResetEvent(m_sMonitorThread.hProcesses[0]);
		m_sMonitorThread.eCommand = PMC_CMDRESET;

		switch(eCommand)
		{
			case PMC_REGISTER_PROCESS:
			{
				m_sMonitorThread.bCmdSuccessful = AmendProcessesInList(&m_sMonitorThread, hCmdParam, IMG_TRUE);
				m_sMonitorThread.bCmdSuccessful = IMG_TRUE;
				break;
			}

			case PMC_UNREGISTER_PROCESS:
			{
				m_sMonitorThread.bCmdSuccessful = AmendProcessesInList(&m_sMonitorThread, hCmdParam, IMG_FALSE);
				m_sMonitorThread.bCmdSuccessful = IMG_TRUE;
				break;
			}
		}
	}

	return(m_sMonitorThread.bCmdSuccessful);
}

/*****************************************************************************/
/****************************** External functions ***************************/
/*****************************************************************************/

/*****************************************************************************
 FUNCTION	: StartResManThread
    
 PURPOSE	: Start the resource manager monitoring thread
 PARAMETERS	: 
			  
 RETURNS	: 
*****************************************************************************/

DWORD MBX::ResManStartThread()
{
	memset(&m_sMonitorThread, 0, sizeof(m_sMonitorThread));

	/* Create Command event */
	if((m_sMonitorThread.hProcesses[0] = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
	{
		return(ERROR_INVALID_PARAMETER);
	}

	m_sMonitorThread.ui32ProcessCnt++;

	/* Create Command completion event */
	if((m_sMonitorThread.hCommandCompletion = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
	{
		CloseHandle(m_sMonitorThread.hProcesses[0]);
		return(ERROR_INVALID_PARAMETER);
	}

	/* Create and start thread */
	if((m_sMonitorThread.hThread = CreateThread(NULL, 0, MonitorThreadProc, &m_sMonitorThread, 0, NULL)) == NULL)
	{
		CloseHandle(m_sMonitorThread.hProcesses[0]);	
		return(ERROR_INVALID_PARAMETER);
	}

	return(ERROR_SUCCESS);
}

/*****************************************************************************
 FUNCTION	: StopResManThread
    
 PURPOSE	: Stop the resource manager monitoring thread
 PARAMETERS	: 
			  
 RETURNS	: 
*****************************************************************************/

DWORD MBX::ResManStopThread()
{
	ResManSendCommand(PMC_TERMINATE_THREAD, NULL);

	WaitForSingleObject(m_sMonitorThread.hThread, 1000);
	
	for(int i=0; i < MAXIMUM_WAIT_OBJECTS; i++)
	{
		if(m_sMonitorThread.hProcesses[i])
		{
			CloseHandle(m_sMonitorThread.hProcesses[i]);
		}
	}

	CloseHandle(m_sMonitorThread.hCommandCompletion);
	CloseHandle(m_sMonitorThread.hThread);

	return(ERROR_SUCCESS);
}

/*****************************************************************************
 FUNCTION	: TermintateProcessRequest
    
 PURPOSE	: Handle terminate process requests sent for the process monitoring
			  thread.
 PARAMETERS	: 
			  
 RETURNS	: 
*****************************************************************************/

DWORD MBX::ResManTermintateProcessRequest(DRVESC_RESMAN_THREAD_TERMINATED_PARAMS	*psResManThreadTerminated)
{
	PVRSRVResManConnect((IMG_UINT32)psResManThreadTerminated->hProcess, IMG_FALSE);

	CloseHandle(psResManThreadTerminated->hProcess);

	return(ERROR_SUCCESS);
}

/*****************************************************************************
 FUNCTION	: ResManConnectProcess
    
 PURPOSE	: Handle terminate process requests sent for the process monitoring
			  thread.
 PARAMETERS	: 
			  
 RETURNS	: 
*****************************************************************************/

DWORD MBX::ResManConnectProcess()
{
	HANDLE	hProcess = GetOwnerProcess(); 

	if(ResManSendCommand(PMC_REGISTER_PROCESS, hProcess))
	{
		PVRSRVResManConnect((IMG_UINT32)hProcess, IMG_TRUE);
	}

	return(ERROR_SUCCESS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -