📄 schedule.c
字号:
if (pth->wCount != pprox->wCount)
bRet = 1;
else {
DEBUGCHK(pth->lpce);
pth->lpce->base = pth->lpProxy;
pth->lpce->size = (DWORD)pth->lpPendProxy;
pth->lpProxy = 0;
pth->wCount++;
if (pth->bWaitState == WAITSTATE_BLOCKED) {
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_RUNNABLE);
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_RUNNING);
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_NEEDSRUN);
pth->retValue = pprox->dwRetVal;
SET_RUNSTATE(pth,RUNSTATE_NEEDSRUN);
*phTh = pth->hTh;
} else {
DEBUGCHK(!GET_SLEEPING(pth));
DEBUGCHK(pth->bWaitState == WAITSTATE_PROCESSING);
pth->dwPendReturn = pprox->dwRetVal;
pth->bWaitState = WAITSTATE_SIGNALLED;
}
lpe->state = 0;
}
}
KCALLPROFOFF(16);
return bRet;
}
void DoFreeMutex(LPMUTEX lpm) {
KCALLPROFON(34);
UnlinkCritMut((LPCRIT)lpm,lpm->pOwner);
KCALLPROFOFF(34);
}
void DoFreeCrit(LPCRIT lpcrit) {
PTHREAD pth;
KCALLPROFON(45);
if (lpcrit->bListed == 1) {
pth = HandleToThread(lpcrit->lpcs->OwnerThread);
DEBUGCHK(pth);
UnlinkCritMut(lpcrit,pth);
}
KCALLPROFOFF(45);
}
/* When a thread tries to closehandle an event */
BOOL SC_EventCloseHandle(HANDLE hEvent) {
HANDLE hTrav;
LPEVENT lpe, lpe2;
DEBUGMSG(ZONE_ENTRY,(L"SC_EventCloseHandle entry: %8.8lx\r\n",hEvent));
CELOG_EventCloseHandle(hEvent);
if (DecRef(hEvent,pCurProc,FALSE)) {
CELOG_EventDelete(hEvent);
EnterCriticalSection(&NameCS);
lpe = HandleToEvent(hEvent);
DEBUGCHK(lpe);
if (hEvent == hEventList)
hEventList = lpe->hNext;
else {
hTrav = hEventList;
lpe2 = HandleToEvent(hTrav);
DEBUGCHK(lpe2);
while (lpe2->hNext != hEvent) {
hTrav = lpe2->hNext;
lpe2 = HandleToEvent(hTrav);
DEBUGCHK(lpe2);
}
lpe2->hNext = lpe->hNext;
}
LeaveCriticalSection(&NameCS);
if (lpe->onequeue) {
while (lpe->pProxList)
KCall((PKFN)DequeueFlatProxy,lpe->pProxList);
} else {
while (lpe->pProxList)
KCall((PKFN)DequeuePrioProxy,lpe->pProxList);
}
if (lpe->name)
FreeName(lpe->name);
if (lpe->pIntrProxy)
FreeIntrFromEvent(lpe);
FreeMem((LPVOID)lpe,HEAP_EVENT);
FreeHandle(hEvent);
}
DEBUGMSG(ZONE_ENTRY,(L"SC_EventCloseHandle exit: %8.8lx\r\n",TRUE));
return TRUE;
}
/* When a thread tries to closehandle a semaphore */
BOOL SC_SemCloseHandle(HANDLE hSem) {
HANDLE hTrav;
LPSEMAPHORE lpsem, lpsem2;
DEBUGMSG(ZONE_ENTRY,(L"SC_SemCloseHandle entry: %8.8lx\r\n",hSem));
CELOG_SemaphoreCloseHandle(hSem);
if (DecRef(hSem,pCurProc,FALSE)) {
CELOG_SemaphoreDelete(hSem);
EnterCriticalSection(&NameCS);
lpsem = HandleToSem(hSem);
DEBUGCHK(lpsem);
if (hSem == hSemList)
hSemList = lpsem->hNext;
else {
hTrav = hSemList;
lpsem2 = HandleToSem(hTrav);
DEBUGCHK(lpsem2);
while (lpsem2->hNext != hSem) {
hTrav = lpsem2->hNext;
lpsem2 = HandleToSem(hTrav);
DEBUGCHK(lpsem2);
}
lpsem2->hNext = lpsem->hNext;
}
LeaveCriticalSection(&NameCS);
while (lpsem->pProxList)
KCall((PKFN)DequeuePrioProxy,lpsem->pProxList);
if (lpsem->name)
FreeName(lpsem->name);
FreeMem((LPVOID)lpsem,HEAP_SEMAPHORE);
FreeHandle(hSem);
}
DEBUGMSG(ZONE_ENTRY,(L"SC_SemCloseHandle exit: %8.8lx\r\n",TRUE));
return TRUE;
}
/* When a thread tries to closehandle a mutex */
BOOL SC_MutexCloseHandle(HANDLE hMutex) {
HANDLE hTrav;
LPMUTEX lpmutex, lpmutex2;
DEBUGMSG(ZONE_ENTRY,(L"SC_MutexCloseHandle entry: %8.8lx\r\n",hMutex));
CELOG_MutexCloseHandle(hMutex);
EnterCriticalSection(&NameCS);
if (DecRef(hMutex,pCurProc,FALSE)) {
CELOG_MutexDelete(hMutex);
lpmutex = HandleToMutex(hMutex);
DEBUGCHK(lpmutex);
if (hMutex == hMutexList)
hMutexList = lpmutex->hNext;
else {
hTrav = hMutexList;
lpmutex2 = HandleToMutex(hTrav);
DEBUGCHK(lpmutex2);
while (lpmutex2->hNext != hMutex) {
hTrav = lpmutex2->hNext;
lpmutex2 = HandleToMutex(hTrav);
DEBUGCHK(lpmutex2);
}
lpmutex2->hNext = lpmutex->hNext;
}
while (lpmutex->pProxList)
if (KCall((PKFN)DequeuePrioProxy,lpmutex->pProxList))
KCall((PKFN)DoReprioMutex,lpmutex);
KCall((PKFN)DoFreeMutex,lpmutex);
if (lpmutex->name)
FreeName(lpmutex->name);
FreeMem((LPVOID)lpmutex,HEAP_MUTEX);
FreeHandle(hMutex);
}
LeaveCriticalSection(&NameCS);
DEBUGMSG(ZONE_ENTRY,(L"SC_MutexCloseHandle exit: %8.8lx\r\n",TRUE));
return TRUE;
}
BOOL SC_EventAddAccess(HANDLE hEvent) {
BOOL retval;
DEBUGMSG(ZONE_ENTRY,(L"SC_EventAddAccess entry: %8.8lx\r\n",hEvent));
if (pCurProc->bTrustLevel != KERN_TRUST_FULL) {
ERRORMSG(1,(L"SC_EventAddAccess failed due to insufficient trust\r\n"));
retval = FALSE;
} else
retval = IncRef(hEvent,pCurProc);
DEBUGMSG(ZONE_ENTRY,(L"SC_EventAddAccess exit: %d\r\n",retval));
return retval;
}
HANDLE EventModIntr(LPEVENT lpe, DWORD type) {
HANDLE hRet;
KCALLPROFON(42);
if (!lpe->pProxList) {
lpe->state = (type == EVENT_SET);
hRet = 0;
} else {
lpe->state = 0;
hRet = WakeOneThreadInterruptDelayed(lpe);
}
DEBUGCHK(!lpe->manualreset);
KCALLPROFOFF(42);
return hRet;
}
void AdjustPrioDown() {
DWORD dwPrio, dwPrio2;
KCALLPROFON(66);
dwPrio = GET_BPRIO(pCurThread);
if (pCurThread->pOwnedList && ((dwPrio2 = pCurThread->pOwnedList->bListedPrio) < dwPrio))
dwPrio = dwPrio2;
SET_CPRIO(pCurThread,dwPrio);
if (RunList.pRunnable && (dwPrio > GET_CPRIO(RunList.pRunnable)))
SetReschedule();
KCALLPROFOFF(66);
}
/* 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 = (bAllKMode ? HandleToEventPerm(hEvent) : HandleToEvent(hEvent)))) {
KSetLastError(pCurThread, ERROR_INVALID_HANDLE);
return FALSE;
}
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;
}
/* When a thread tries to create an event */
HANDLE SC_CreateEvent(LPSECURITY_ATTRIBUTES lpsa, BOOL fManReset, BOOL fInitState, LPCWSTR lpEventName) {
HANDLE hEvent;
LPEVENT lpe;
int len;
DEBUGMSG(ZONE_ENTRY,(L"SC_CreateEvent entry: %8.8lx %8.8lx %8.8lx %8.8lx\r\n",
lpsa,fManReset,fInitState,lpEventName));
if (lpEventName) {
len = strlenW(lpEventName) + 1;
if (len > MAX_PATH) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
DEBUGMSG(ZONE_ENTRY,(L"SC_CreateEvent exit: %8.8lx\r\n",0));
return 0;
}
len *= sizeof(WCHAR);
LockPages(lpEventName,len,0,LOCKFLAG_READ);
}
EnterCriticalSection(&NameCS);
if (lpEventName) {
for (hEvent = hEventList; hEvent; hEvent = lpe->hNext) {
lpe = HandleToEvent(hEvent);
DEBUGCHK(lpe);
if (lpe->name && !strcmpW(lpe->name->name,lpEventName)) {
IncRef(hEvent,pCurProc);
KSetLastError(pCurThread,ERROR_ALREADY_EXISTS);
goto exit;
}
}
KSetLastError(pCurThread,0);
}
if (!(lpe = (LPEVENT)AllocMem(HEAP_EVENT))) {
KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
hEvent = 0;
goto exit;
}
if (!(hEvent = AllocHandle(&cinfEvent,lpe,pCurProc))) {
KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
FreeMem(lpe,HEAP_EVENT);
hEvent = 0;
goto exit;
}
if (lpEventName) {
if (!(lpe->name = (Name *)AllocName(len))) {
KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
FreeHandle(hEvent);
FreeMem(lpe,HEAP_EVENT);
hEvent = 0;
goto exit;
}
memcpy(lpe->name->name,lpEventName,len);
} else
lpe->name = 0;
memset(lpe->pProxHash,0,sizeof(lpe->pProxHash));
lpe->pProxList = 0;
lpe->hNext = hEventList;
hEventList = hEvent;
lpe->state = fInitState;
lpe->manualreset = fManReset;
lpe->onequeue = fManReset;
lpe->pIntrProxy = 0;
lpe->bMaxPrio = THREAD_RT_PRIORITY_IDLE;
exit:
CELOG_EventCreate(hEvent, fManReset, fInitState, lpEventName);
LeaveCriticalSection(&NameCS);
if (lpEventName)
UnlockPages(lpEventName,len);
DEBUGMSG(ZONE_ENTRY,(L"SC_CreateEvent exit: %8.8lx\r\n",hEvent));
return hEvent;
}
/* When a thread tries to create a semaphore */
HANDLE SC_CreateSemaphore(LPSECURITY_ATTRIBUTES lpsa, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName) {
HANDLE hSem;
int len;
LPSEMAPHORE lpsem;
DEBUGMSG(ZONE_ENTRY,(L"SC_CreateSemaphore entry: %8.8lx %8.8lx %8.8lx %8.8lx\r\n",lpsa,lInitialCount,lMaximumCount,lpName));
if (lpName) {
len = strlenW(lpName) + 1;
if (len > MAX_PATH) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
DEBUGMSG(ZONE_ENTRY,(L"SC_CreateSemaphore exit: %8.8lx\r\n",0));
return 0;
}
len *= sizeof(WCHAR);
LockPages(lpName,len,0,LOCKFLAG_READ);
}
EnterCriticalSection(&NameCS);
if (lpName) {
for (hSem = hSemList; hSem; hSem = lpsem->hNext) {
lpsem = HandleToSem(hSem);
DEBUGCHK(lpsem);
if (lpsem->name && !strcmpW(lpsem->name->name,lpName)) {
IncRef(hSem,pCurProc);
KSetLastError(pCurThread,ERROR_ALREADY_EXISTS);
goto exit;
}
}
KSetLastError(pCurThread,0);
}
if ((lInitialCount < 0) || (lMaximumCount <= 0) || lpsa || (lInitialCount > lMaximumCount)) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
hSem = 0;
goto exit;
}
if (!(lpsem = (LPSEMAPHORE)AllocMem(HEAP_SEMAPHORE))) {
KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
hSem = 0;
goto exit;
}
if (!(hSem = AllocHandle(&cinfSem,lpsem,pCurProc))) {
KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
FreeMem(lpsem,HEAP_SEMAPHORE);
hSem = 0;
goto exit;
}
if (lpName) {
if (!(lpsem->name = (Name *)AllocName(len))) {
KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
FreeHandle(hSem);
FreeMem(lpsem,HEAP_SEMAPHORE);
hSem = 0;
goto exit;
}
memcpy(lpsem->name->name,lpName,len);
} else
lpsem->name = 0;
memset(lpsem->pProxHash,0,sizeof(lpsem->pProxHash));
lpsem->pProxList = 0;
lpsem->hNext = hSemList;
hSemList = hSem;
lpsem->lCount = lInitialCount;
lpsem->lMaxCount = lMaximumCount;
lpsem->lPending = 0;
exit:
CELOG_SemaphoreCreate(hSem, lInitialCount, lMaximumCount, lpName);
LeaveCriticalSection(&NameCS);
if (lpName)
UnlockPages(lpName,len);
DEBUGMSG(ZONE_ENTRY,(L"SC_CreateSemaphore exit: %8.8lx\r\n",hSem));
return hSem;
}
/* When a thread tries to create a mutex */
HANDLE SC_CreateMutex(LPSECURITY_ATTRIBUTES lpsa, BOOL bInitialOwner, LPCTSTR lpName) {
int len;
HANDLE hMutex;
LPMUTEX lpmutex;
DEBUGMSG(ZONE_ENTRY,(L"SC_CreateMutex entry: %8.8lx %8.8lx %8.8lx\r\n",lpsa,bInitialOwner,lpName));
if (lpName) {
len = strlenW(lpName) + 1;
if (len > MAX_PATH) {
KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
DEBUGMSG(ZONE_ENTRY,(L"SC_CreateMutex exit: %8.8lx\r\n",0));
return 0;
}
len *= sizeof(WCHAR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -