📄 sdworkitem.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// Copyright (c) 2002 BSQUARE Corporation. All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE
// Class implementation of work item
#include "SDBusDriver.h"
// enqueue a message
_inline VOID EnqueueMessageToQueue(PLIST_ENTRY pListHead, PWORK_ITEM_MESSAGE_BLOCK pMessage)
{
// insert to the tail
InsertTailList(pListHead, &pMessage->ListEntry);
}
///////////////////////////////////////////////////////////////////////////////
// DequeueMessageFromQueue - dequeue a message block from the queue
// Input: pListHead - queue containing the message
// Output:
// Return: NULL if list is empty otherwise the message block
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
PWORK_ITEM_MESSAGE_BLOCK DequeueMessageFromQueue(PLIST_ENTRY pListHead)
{
PLIST_ENTRY pListEntry; // list entry
if (IsListEmpty(pListHead)) {
return NULL;
}
// dequeue from the head
pListEntry = RemoveHeadList(pListHead);
return CONTAINING_RECORD(pListEntry, WORK_ITEM_MESSAGE_BLOCK, ListEntry);
}
///////////////////////////////////////////////////////////////////////////////
// CSDWorkItem - constructor
// Input: pContext - context for the work item
// pFunction - main work item function
// Priority - work item priority
// MessageListDepth - initial message block depth
// MessageBlockLength - the length of the message block
// MessageQueue - use a message queue
// Output:
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
CSDWorkItem::CSDWorkItem(PVOID pContext,
PSD_WORK_ITEM_FUNC pFunction,
int Priority,
ULONG MessageListDepth,
ULONG MessageBlockLength,
BOOL MessageQueue)
{
m_pWorkFunction = pFunction;
m_pWorkItemContext = pContext;
m_ShutDown = FALSE;
m_WorkItemPriority = Priority;
m_hWorkItemMessageList = NULL;
InitializeCriticalSection(&m_CriticalSection);
InitializeListHead(&m_WorkItemMessageQueue);
m_MessageListDepth = MessageListDepth;
m_MessageBlockLength = MessageBlockLength;
m_Initialized = FALSE;
m_UseMessageQueue = MessageQueue;
}
///////////////////////////////////////////////////////////////////////////////
// ~CSDWorkItem - destructor
// Input:
// Output:
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
CSDWorkItem::~CSDWorkItem()
{
if (m_Initialized) {
if (UsingMessageQueue()) {
FlushMessageQueue();
}
m_Initialized = FALSE;
}
// flag for shutdown
m_ShutDown = TRUE;
if (NULL != m_hWorkerThread) {
// wake up the worker
SetEvent(m_hWorkerWakeUp);
WaitForSingleObject(m_hWorkerThread, INFINITE);
CloseHandle(m_hWorkerThread);
m_hWorkerThread = NULL;
}
if (NULL != m_hWorkerWakeUp){
CloseHandle(m_hWorkerWakeUp);
m_hWorkerWakeUp = NULL;
}
if (NULL != m_hWorkItemMessageList) {
SDDeleteMemList(m_hWorkItemMessageList);
m_hWorkItemMessageList = NULL;
}
DeleteCriticalSection(&m_CriticalSection);
}
///////////////////////////////////////////////////////////////////////////////
// FlushMessageQueue - flush the message queue of all outstanding events
// Input:
// Output:
// Return:
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
VOID CSDWorkItem::FlushMessageQueue()
{
PWORK_ITEM_MESSAGE_BLOCK pMessage; // slot event
// acquire the lock to protect the list
AcquireLock();
// move through the message queue and empty it out
while ((pMessage = DequeueMessageFromQueue(&m_WorkItemMessageQueue)) != NULL) {
FreeMessage(pMessage);
}
ReleaseLock();
}
///////////////////////////////////////////////////////////////////////////////
// WorkItemThreadEntry - entry point for work item thread
// Input: pWorkItem - work item
// Output:
// Return: returns thread exit code (zero)
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
DWORD CSDWorkItem::WorkItemThreadEntry(CSDWorkItem *pWorkItem)
{
pWorkItem->m_pWorkFunction(pWorkItem , pWorkItem->GetContext());
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// StartWorkItem - create a work item
// Input:
// Output:
// Return: SD_API_STATUS code
// Notes:
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDWorkItem::StartWorkItem()
{
DWORD threadID; // thread ID
if (UsingMessageQueue()) {
// create work item message list
m_hWorkItemMessageList = SDCreateMemoryList(SD_BUS_DRIVER_WORKER_TAG,
m_MessageListDepth,
m_MessageBlockLength + sizeof(WORK_ITEM_MESSAGE_BLOCK) - sizeof(DWORD));
if (NULL == m_hWorkItemMessageList) {
return SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
}
// create the wake up event
m_hWorkerWakeUp = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == m_hWorkerWakeUp) {
return SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
// create the actual worker thread
m_hWorkerThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)CSDWorkItem::WorkItemThreadEntry,
this,
CREATE_SUSPENDED,
&threadID);
if (NULL == m_hWorkerThread) {
return SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
if (!CeSetThreadPriority(m_hWorkerThread, m_WorkItemPriority)) {
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: CeSetThreadPriority Failed! \n")));
}
ResumeThread(m_hWorkerThread);
m_Initialized = TRUE;
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// PostMessage - post a message
// Input: pMessage - message to post
// Output:
// Return:
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
VOID CSDWorkItem::PostMessage(PWORK_ITEM_MESSAGE_BLOCK pMessage)
{
if (UsingMessageQueue()) {
AcquireLock();
EnqueueMessageToQueue(&m_WorkItemMessageQueue, pMessage);
ReleaseLock();
WakeUpWorkItem();
} else {
DEBUGCHK(FALSE);
}
}
///////////////////////////////////////////////////////////////////////////////
// GetMessage - get a message
// Input:
// Output: ppMessage - message that was retreived
// Return: This function returns SD_API_STATUS_SUCCESS if a message arrived
// Notes:
//
// This function should be called in a loop until it blocks.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDWorkItem::GetMessage(PWORK_ITEM_MESSAGE_BLOCK *ppMessage)
{
SD_API_STATUS status; // intermediate status
if (UsingMessageQueue()) {
// check for a message
AcquireLock();
*ppMessage = DequeueMessageFromQueue(&m_WorkItemMessageQueue);
ReleaseLock();
if (*ppMessage != NULL) {
// return immediately, the caller should call this function
// again to drain the queue
return SD_API_STATUS_SUCCESS;
}
while (1) {
// no messages left, go into wait
status = WaitWakeUp();
if (!SD_API_SUCCESS(status)) {
return status;
}
// check for a new message
AcquireLock();
*ppMessage = DequeueMessageFromQueue(&m_WorkItemMessageQueue);
ReleaseLock();
if (*ppMessage != NULL) {
break;
}
// if there wasn't a message go back and wait
}
return SD_API_STATUS_SUCCESS;
} else {
DEBUGCHK(FALSE);
return SD_API_STATUS_UNSUCCESSFUL;
}
}
///////////////////////////////////////////////////////////////////////////////
// WaitWakeUp - wait on a wake up event
// Input: TimeOut - the time out to wake up immediately
// Output:
// Return: SD_API_STATUS code
// Notes:
// This function blocks on the work item wakeup event until the event is
// signalled or a timeout occurs
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDWorkItem::WaitWakeUp(DWORD TimeOut)
{
DWORD waitStatus; // wait status
RETAILMSG(0,(TEXT("CSDWorkItem=0x%08X m_hWorkerWakeUp=0x%08X\n"),this,m_hWorkerWakeUp));
waitStatus = WaitForSingleObject(m_hWorkerWakeUp, TimeOut);
RETAILMSG(0,(TEXT("CSDWorkItem::WaitWakeUp\n")));
// check for shutdown
if (m_ShutDown){
return SD_API_STATUS_SHUT_DOWN;
}
// check for wait failure
if (waitStatus != WAIT_OBJECT_0) {
return SD_API_STATUS_UNSUCCESSFUL;
}
return SD_API_STATUS_SUCCESS;
}
// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -