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

📄 schedule.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    DEBUGMSG(ZONE_ENTRY,(L"SC_EventGetData entry: %8.8lx\r\n",hEvent));
    if (!(lpe = HandleToEventPerm(hEvent))) {
        KSetLastError(pCurThread, ERROR_INVALID_HANDLE);
        DEBUGMSG(ZONE_ENTRY,(L"SC_EventGetData exit: -1\r\n"));
        return 0;
    }

    if (!lpe->dwData) {
        KSetLastError (pCurThread, 0);  // no error
    }

    DEBUGMSG(ZONE_ENTRY,(L"SC_EventGetData exit: %8.8lx\r\n", lpe->dwData));
    return lpe->dwData;

}

/* When a thread tries to set/reset/pulse an event */



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
SC_EventModify(
    HANDLE hEvent,
    DWORD type
    ) 
{
    LPEVENT lpe;
    HANDLE hWake;
    LPSTUBEVENT lpse;
    DEBUGMSG(ZONE_ENTRY,(L"SC_EventModify entry: %8.8lx %8.8lx\r\n",hEvent,type));
    if (!(lpe = HandleToEventPerm(hEvent))) {
        KSetLastError(pCurThread, ERROR_INVALID_HANDLE);
        return FALSE;
    }
    
    if (IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)) {
        CELOG_Event(hEvent, type);
    }

    switch (type) {
    case EVENT_PULSE:
    case EVENT_SET:
        if (lpe->pIntrProxy) {
            DEBUGCHK(lpe->onequeue);
            if (hWake = (HANDLE)KCall((PKFN)EventModIntr,lpe,type))
                KCall((PKFN)MakeRunIfNeeded,hWake);
        } else if (lpe->manualreset) {
            DWORD dwOldPrio, dwNewPrio;
            DEBUGCHK(lpe->onequeue);
            // *lpse can't be stack-based since other threads won't have access and might dequeue/requeue
            if (!(lpse = AllocMem(HEAP_STUBEVENT))) {
                DEBUGMSG(ZONE_ENTRY,(L"SC_EventModify exit: %8.8lx\r\n",FALSE));
                KSetLastError(pCurThread,ERROR_OUTOFMEMORY);
                return FALSE;
            }
            dwOldPrio = GET_BPRIO(pCurThread);
            dwNewPrio = KCall((PKFN)EventModMan,lpe,lpse,type);
            if (lpse->pProxList) {
                SET_NOPRIOCALC(pCurThread);
                if (dwNewPrio < dwOldPrio)
                    SET_CPRIO(pCurThread,dwNewPrio);
                while (lpse->pProxList) {
                    hWake = 0;
                    KCall((PKFN)WakeOneThreadFlat,lpse,&hWake);
                    if (hWake)
                        KCall((PKFN)MakeRunIfNeeded,hWake);
                }
                CLEAR_NOPRIOCALC(pCurThread);
                if (dwNewPrio < dwOldPrio)
                    KCall((PKFN)AdjustPrioDown);
            }
            FreeMem(lpse,HEAP_STUBEVENT);
        } else {
            hWake = 0;
            while (KCall((PKFN)EventModAuto,lpe,type,&hWake))
                ;
            if (hWake)
                KCall((PKFN)MakeRunIfNeeded,hWake);
        }
        break;
    case EVENT_RESET:
        lpe->state = 0;
        break;
    default:
        DEBUGCHK(0);
    }
    DEBUGMSG(ZONE_ENTRY,(L"SC_EventModify exit: %8.8lx\r\n",TRUE));
    return TRUE;
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL 
IsValidIntrEvent(
    HANDLE hEvent
    ) 
{
    EVENT *lpe;
    if (!(lpe = HandleToEvent(hEvent)) || lpe->manualreset || lpe->pProxList)
        return FALSE;
    return TRUE;
}

typedef DWORD (* PFN_InitSyncObj) (HANDLE hObj, LPVOID pObj, DWORD dwParam1, DWORD dwParam2, LPName pName);
typedef void (* PFN_DeInitSyncObj) (HANDLE hObj, LPVOID pObj);
typedef LPName (* PFN_GetName) (LPVOID pObj);

//
// structure to define object specific methods of kernel sync-objects (mutex, event, and semaphore)
// NOTE: name comparision is object specific because it's not at the same offset
//       for individual objects. We should probabaly look into changing the structures
//       so they're at the same offset and then we don't need a compare-name method.
//
typedef struct _SYNCOBJ_METHOD {
    PFN_InitSyncObj     pfnInit;
    PFN_DeInitSyncObj   pfnDeInit;
    PFN_GetName         pfnGetName;
    const CINFO         *pci;
    LPCRITICAL_SECTION  lpcs;
} SYNCOBJ_METHOD, *PSYNCOBJ_METHOD;

//------------------------------------------------------------------------------
// initialize a mutex
//------------------------------------------------------------------------------
static DWORD InitMutex (HANDLE hObj, LPVOID pObj, DWORD bInitialOwner, DWORD unused, LPName pName)
{
    LPMUTEX pMutex = (LPMUTEX) pObj;
    pMutex->name = pName;
    if (bInitialOwner) {
        pMutex->LockCount = 1;
        pMutex->pOwner = pCurThread;
        KCall ((PKFN)LaterLinkCritMut, pMutex, 0);
    }
    if (IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)) {
        CELOG_MutexCreate(hObj, pMutex);
    }
    return 0;   // no error
}

//------------------------------------------------------------------------------
// initialize an event
//------------------------------------------------------------------------------
static DWORD InitEvent (HANDLE hObj, LPVOID pObj, DWORD fManualReset, DWORD fInitState, LPName pName)
{
    LPEVENT pEvent = (LPEVENT) pObj;
    pEvent->name = pName;
    pEvent->state = (BYTE) fInitState;
    pEvent->manualreset = pEvent->onequeue = (BYTE) fManualReset;
    pEvent->bMaxPrio = THREAD_RT_PRIORITY_IDLE;
    if (IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)) {
        CELOG_EventCreate(hObj, fManualReset, fInitState, pName? pName->name : NULL, TRUE);
    }
    return 0;   // no error
}

//------------------------------------------------------------------------------
// initialize a semaphore
//------------------------------------------------------------------------------
static DWORD InitSemaphore (HANDLE hObj, LPVOID pObj, DWORD lInitCount, DWORD lMaxCount, LPName pName)
{
    LPSEMAPHORE pSem = (LPSEMAPHORE) pObj;
    if (((LONG) lInitCount < 0) || ((LONG) lMaxCount < 0) || (lInitCount > lMaxCount))
        return ERROR_INVALID_PARAMETER;
    pSem->name = pName;
    pSem->lMaxCount = (LONG) lMaxCount;
    pSem->lCount = (LONG) lInitCount;
    
    if (IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)) {
        CELOG_SemaphoreCreate(hObj, (LONG) lInitCount, (LONG) lMaxCount, pName? pName->name : NULL);
    }

    return 0;   // no error
}

//------------------------------------------------------------------------------
// delete a mutex
//------------------------------------------------------------------------------
static void DeInitMutex (HANDLE hObj, LPVOID pObj)
{
    LPMUTEX pMutex = (LPMUTEX) pObj;
    BOOL fOtherWaiting = FALSE;

    if (IsCeLogStatus(CELOGSTATUS_ENABLED_ANY)) {
        CELOG_MutexDelete (hObj);
    }

    while (pMutex->pProxList) {
        if (KCall ((PKFN)DequeuePrioProxy, pMutex->pProxList)) {
            KCall ((PKFN)DoReprioMutex, pMutex);
            fOtherWaiting = TRUE;
        }
    }

    KCall ((PKFN)DoFreeMutex, pMutex);

    if (pMutex->name)
        FreeName (pMutex->name);

    DEBUGMSG (fOtherWaiting, (L"WARNING: Mutex %8.8lx is deleted while other thread is waiting for it\r\n", hObj));
    DEBUGCHK (!fOtherWaiting);
}

//------------------------------------------------------------------------------
// delete an event
//------------------------------------------------------------------------------
static void DeInitEvent (HANDLE hObj, LPVOID pObj)
{
    LPEVENT pEvent = (LPEVENT) pObj;
    PKFN pfnDequeue = pEvent->onequeue? (PKFN) DequeueFlatProxy : (PKFN) DequeuePrioProxy;
    BOOL fOtherWaiting = FALSE;

    if (IsCeLogStatus(CELOGSTATUS_ENABLED_ANY)) {
        CELOG_EventDelete (hObj);
    }

    // delete the watchdog object if this is a watchdog event
    if (pEvent->dwData) {
        WDDelete (hObj);
    }

    while (pEvent->pProxList) {
        if (KCall (pfnDequeue, pEvent->pProxList))
            fOtherWaiting = TRUE;
    }

    if (pEvent->name)
        FreeName (pEvent->name);
    if (pEvent->pIntrProxy)
        FreeIntrFromEvent (pEvent);
    
    DEBUGMSG (fOtherWaiting, (L"WARNING: Event %8.8lx is deleted while other thread is waiting for it\r\n", hObj));
}

//------------------------------------------------------------------------------
// delete a semaphore
//------------------------------------------------------------------------------
static void DeInitSemaphore (HANDLE hObj, LPVOID pObj)
{
    LPSEMAPHORE pSem = (LPSEMAPHORE) pObj;
    BOOL fOtherWaiting = FALSE;
    
    if (IsCeLogStatus(CELOGSTATUS_ENABLED_ANY)) {
        CELOG_SemaphoreDelete (hObj);
    }

    while (pSem->pProxList) {
        if (KCall ((PKFN)DequeuePrioProxy, pSem->pProxList))
            fOtherWaiting = TRUE;
    }

    if (pSem->name)
        FreeName (pSem->name);
    
    DEBUGMSG (fOtherWaiting, (L"WARNING: Semaphore %8.8lx is deleted while other thread is waiting for it\r\n", hObj));
}

//------------------------------------------------------------------------------
// get name of a mutex
//------------------------------------------------------------------------------
static LPName MutexGetName (LPVOID pObj)
{
    return ((LPMUTEX) pObj)->name;
}

//------------------------------------------------------------------------------
// get name of a event
//------------------------------------------------------------------------------
static LPName EventGetName (LPVOID pObj)
{
    return ((LPEVENT) pObj)->name;
}

//------------------------------------------------------------------------------
// get name of a semaphore
//------------------------------------------------------------------------------
static LPName SemGetName (LPVOID pObj)
{
    return ((LPSEMAPHORE) pObj)->name;
}

//
// Event methods
//
static SYNCOBJ_METHOD eventMethod = { 
    InitEvent,
    DeInitEvent,
    EventGetName,
    &cinfEvent,
    &EventCS,
    };

//
// Mutex methods
//
static SYNCOBJ_METHOD mutexMethod = {
    InitMutex,
    DeInitMutex,
    MutexGetName,
    &cinfMutex,
    &MutexCS,
    };

//
// Semaphore methods
//
static SYNCOBJ_METHOD semMethod   = {
    InitSemaphore,
    DeInitSemaphore,
    SemGetName,
    &cinfSem,
    &SemCS,
    };


//------------------------------------------------------------------------------
// common function to create/open a sync-object
//------------------------------------------------------------------------------
static HANDLE OpenOrCreateSyncObject (
    LPSECURITY_ATTRIBUTES   lpsa,
    DWORD                   dwParam1, 
    DWORD                   dwParam2, 
    LPCWSTR                 pszName,
    HANDLE                  *phHandleList, 
    PSYNCOBJ_METHOD         pObjMethod,
    BOOL                    fCreate)
{
    int     len = 0;
    DWORD   dwErr = 0;
    HANDLE  hObj = NULL;
    LPVOID  pObj;
    DWORD   dwSavedLastErr = KGetLastError (pCurThread);

    // error if open existing without a name
    if (!fCreate && !pszName) {
        KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
        return NULL;
    }

    // validate parameters
    if (pszName) {
        // caller needs to be trusted if the named object is system prefixed (case insensitive)
        if (!kstrncmpi (pszName, TEXT("SYSTEM/"), 7)) {
            TRUSTED_API (L"OpenOrCreateSyncObject", NULL);
        }
        // try to find it in the list if name is supplied
        len = strlenW(pszName) + 1;
        if ((MAX_PATH < len) || !LockPages(pszName, len *= sizeof(WCHAR), 0, LOCKFLAG_READ)) {
            KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);
            return NULL;
        }
    }

    EnterCriticalSection(pObjMethod->lpcs);

    // try to find if name exists
    if (pszName) {
        for (hObj = *phHandleList; hObj; hObj = ((LPEVENT) pObj)->hNext) {
            LPName pObjName;
            pObj = GetObjectPtrByType (hObj, pObjMethod->pci->type);
            DEBUGCHK (pObj);
            pObjName = pObjMethod->pfnGetName (pObj);
            if (pObjName && !strcmpW (pObjName->name, pszName)) {
                // object already exist, 
                if (ACLCheck (hObj)) {
                    // increment ref-count and done
                    IncRef (hObj, pCurProc);
                    dwErr = ERROR_ALREADY_EXISTS;
                } else {
                    // no access
                    dwErr = ERROR_ACCESS_DENIED;
                    hObj = NULL;
                }
                break;
            }
        }
    }

    // error if open existing but not found
    if (!fCreate && !hObj && !dwErr) {
        dwErr = ERROR_FILE_NOT_FOUND;
    } else if (!dwErr) {
        dwSavedLastErr = 0;
    }

    if (!dwErr) {
        // create a new object
        LPName pName = NULL, psd = NULL;
        if ((pObj = AllocMem (HEAP_SYNC_OBJ))
            && (hObj = AllocHandle (pObjMethod->pci, pObj, pCurProc))
            && (!len || (pName = AllocName (len)))
            && (!lpsa || !(dwErr = AllocPSD (lpsa, &psd)))) {

            // clear memory

⌨️ 快捷键说明

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