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

📄 sdworkitem.cpp

📁 2443 wince5.0 bsp, source code
💻 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 + -