Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

taskman.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: taskman.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains the core functions of the input sub-system 00007 * 00008 * History: 00009 * 02-27-91 MikeHar Created. 00010 * 02-23-92 MattFe rewrote sleeptask 00011 * 09-07-93 DaveHart Per-process nonpreemptive scheduler for 00012 * multiple WOW VDM support. 00013 \***************************************************************************/ 00014 00015 #include "precomp.h" 00016 #pragma hdrstop 00017 00018 00019 /* 00020 * WakeWowTask 00021 * 00022 * if needed the wowtask is woken by setting its event 00023 * It is assumed that if any wow task is currently scheduled 00024 * that it is a waste of time to wake the specified wow task 00025 * since rescheduling will occur when the currently scheduled 00026 * wow task enters xxxSleepTask 00027 * 00028 */ 00029 VOID 00030 WakeWowTask( 00031 PTHREADINFO pti 00032 ) 00033 { 00034 PWOWPROCESSINFO pwpi; 00035 00036 pwpi = pti->ppi->pwpi; 00037 if (pwpi && !pwpi->ptiScheduled) { 00038 KeSetEvent(pti->pEventQueueServer, EVENT_INCREMENT, FALSE); 00039 } 00040 } 00041 00042 00043 00044 00045 /***************************************************************************\ 00046 * InsertTask 00047 * 00048 * This function removes a task from its old location and inserts 00049 * in the proper prioritized location 00050 * 00051 * Find a place for this task such that it must be inserted 00052 * after any task with greater or equal priority and must be 00053 * before any task with higher priorty. The higher the priority 00054 * the less urgent the task. 00055 * 00056 * History: 00057 * 19-Nov-1993 mikeke Created 00058 \***************************************************************************/ 00059 00060 void InsertTask( 00061 PPROCESSINFO ppi, 00062 PTDB ptdbNew) 00063 { 00064 PTDB *pptdb; 00065 PTDB ptdb; 00066 int nPriority; 00067 PWOWPROCESSINFO pwpi = ppi->pwpi; 00068 00069 CheckCritIn(); 00070 00071 UserAssert(pwpi != NULL); 00072 00073 pptdb = &pwpi->ptdbHead; 00074 nPriority = ptdbNew->nPriority; 00075 00076 while ((ptdb = *pptdb) != NULL) { 00077 /* 00078 * Remove it from it's old location 00079 */ 00080 if (ptdb == ptdbNew) { 00081 *pptdb = ptdbNew->ptdbNext; 00082 00083 /* 00084 * continue to search for the place to insert it 00085 */ 00086 while ((ptdb = *pptdb) != NULL) { 00087 if (nPriority < ptdb->nPriority) { 00088 break; 00089 } 00090 00091 pptdb = &(ptdb->ptdbNext); 00092 } 00093 break; 00094 } 00095 00096 /* 00097 * if this is the place to insert continue to search for the 00098 * place to delete it from 00099 */ 00100 if (nPriority < ptdb->nPriority) { 00101 do { 00102 if (ptdb->ptdbNext == ptdbNew) { 00103 ptdb->ptdbNext = ptdbNew->ptdbNext; 00104 break; 00105 } 00106 ptdb = ptdb->ptdbNext; 00107 } while (ptdb != NULL); 00108 break; 00109 } 00110 00111 pptdb = &(ptdb->ptdbNext); 00112 } 00113 00114 /* 00115 * insert the new task 00116 */ 00117 ptdbNew->ptdbNext = *pptdb; 00118 *pptdb = ptdbNew; 00119 } 00120 00121 00122 /***************************************************************************\ 00123 * DestroyTask() 00124 * 00125 * History: 00126 * 02-27-91 MikeHar Created. 00127 \***************************************************************************/ 00128 00129 void DestroyTask( 00130 PPROCESSINFO ppi, 00131 PTHREADINFO ptiToRemove) 00132 { 00133 PTDB ptdbToRemove = ptiToRemove->ptdb; 00134 PTDB ptdb; 00135 PTDB* pptdb; 00136 PWOWPROCESSINFO pwpi = ppi->pwpi; 00137 00138 // try to catch #150446 00139 CheckCritIn(); 00140 BEGINATOMICCHECK(); 00141 00142 UserAssert(pwpi != NULL); 00143 00144 if (ptdbToRemove != NULL) { 00145 00146 if (ptdbToRemove->TDB_Flags & TDBF_SETUP) { 00147 /* 00148 * This means that the WoW app was a setup app (checked in SetAppCompatFlags). 00149 * If so, the shell needs to be notified so it can clean up potential problems 00150 * caused by bad calls to DDE, etc. FritzS 00151 */ 00152 PDESKTOPINFO pdeskinfo = GETDESKINFO(ptiToRemove); 00153 if (pdeskinfo->spwndShell) { 00154 _PostMessage(pdeskinfo->spwndShell, DTM_SETUPAPPRAN, 0, 0); 00155 } 00156 } 00157 /* 00158 * Remove the WOW per thread info 00159 */ 00160 if (ptdbToRemove->pwti) { 00161 PWOWTHREADINFO *ppwti = &gpwtiFirst; 00162 while (*ppwti != ptdbToRemove->pwti && (*ppwti)->pwtiNext != NULL) { 00163 ppwti = &((*ppwti)->pwtiNext); 00164 } 00165 if (*ppwti == ptdbToRemove->pwti) { 00166 *ppwti = ptdbToRemove->pwti->pwtiNext; 00167 } 00168 CLOSE_PSEUDO_EVENT(&ptdbToRemove->pwti->pIdleEvent); 00169 UserFreePool(ptdbToRemove->pwti); 00170 } 00171 00172 gpsi->nEvents -= ptdbToRemove->nEvents; 00173 00174 /* 00175 * remove it from any lists 00176 */ 00177 pptdb = &pwpi->ptdbHead; 00178 while ((ptdb = *pptdb) != NULL) { 00179 /* 00180 * Remove it from it's old location 00181 */ 00182 if (ptdb == ptdbToRemove) { 00183 *pptdb = ptdb->ptdbNext; 00184 UserFreePool(ptdbToRemove); 00185 UserAssert(ptiToRemove->ptdb == ptdbToRemove); 00186 ptiToRemove->ptdb = NULL; 00187 break; 00188 } 00189 pptdb = &(ptdb->ptdbNext); 00190 } 00191 UserAssert(ptdb == ptdbToRemove); // #150446 check that we actually found it 00192 } 00193 ENDATOMICCHECK(); // #150446 00194 00195 /* 00196 * If the task being destroyed is the active task, make nobody active. 00197 * We will go through this code path for 32-bit threads that die while 00198 * Win16 threads are waiting for a SendMessage reply from them. 00199 */ 00200 if (pwpi->ptiScheduled == ptiToRemove) { 00201 pwpi->ptiScheduled = NULL; 00202 ExitWowCritSect(ptiToRemove, pwpi); 00203 00204 /* 00205 * If this active task was locked, remove lock so next guy can 00206 * run. 00207 */ 00208 pwpi->nTaskLock = 0; 00209 00210 00211 /* 00212 * Wake next task with events, or wowexec to run the scheduler 00213 */ 00214 if (pwpi->ptdbHead != NULL) { 00215 PTDB ptdb; 00216 00217 for (ptdb = pwpi->ptdbHead; ptdb; ptdb = ptdb->ptdbNext) { 00218 if (ptdb->nEvents > 0) { 00219 KeSetEvent(ptdb->pti->pEventQueueServer, 00220 EVENT_INCREMENT, FALSE); 00221 break; 00222 } 00223 } 00224 00225 if (!ptdb) { 00226 KeSetEvent(pwpi->pEventWowExec, EVENT_INCREMENT, FALSE); 00227 } 00228 } 00229 } 00230 UserAssert(ptiToRemove != pwpi->CSOwningThread); 00231 00232 } 00233 00234 00235 00236 00237 /***************************************************************************\ 00238 * xxxSleepTask 00239 * 00240 * This function puts this task to sleep and wakes the next (if any) 00241 * deserving task. 00242 * 00243 * BOOL fInputIdle - app is going idle, may do idle hooks 00244 * HANDLE hEvent - if nonzero, WowExec's event (client side) for 00245 * virtual HW Interrupt HotPath. 00246 * History: 00247 * 02-27-91 MikeHar Created. 00248 * 02-23-91 MattFe rewrote 00249 * 12-17-93 Jonle add wowexec hotpath for VirtualInterrupts 00250 \***************************************************************************/ 00251 00252 BOOL xxxSleepTask( 00253 BOOL fInputIdle, 00254 HANDLE hEvent) 00255 { 00256 PTDB ptdb; 00257 PTHREADINFO pti; 00258 PPROCESSINFO ppi; 00259 PWOWPROCESSINFO pwpi; 00260 PSMS psms; 00261 NTSTATUS Status; 00262 int nHandles; 00263 BOOLEAN bWaitedAtLeastOnce; 00264 00265 /* 00266 * !!! 00267 * ClearSendMessages assumes that this function does NOT leave the 00268 * critical section when called with fInputIdle==FALSE and from a 00269 * 32bit thread! 00270 */ 00271 00272 CheckCritIn(); 00273 00274 pti = PtiCurrent(); 00275 ppi = pti->ppi; 00276 pwpi = ppi->pwpi; 00277 00278 /* 00279 * If this task has received a message from outside of the current 00280 * wow scheduler and hasn't yet replied to the message, the scheduler 00281 * will deadlock because the send\receive lock counts are updated 00282 * in ReplyMessage and not in receive message. Check for this 00283 * condition and do the DirectedSchedukeTask that normally occurs 00284 * in ReplyMessage. 16-Feb-1995 Jonle 00285 */ 00286 psms = pti->psmsCurrent; 00287 if (psms && psms->ptiReceiver == pti && 00288 psms->ptiSender && !(psms->flags & SMF_REPLY) && 00289 psms->flags & (SMF_RECEIVERBUSY | SMF_RECEIVEDMESSAGE) && 00290 psms->ptiSender->TIF_flags & TIF_16BIT && 00291 (pwpi != psms->ptiSender->ppi->pwpi || !(pti->TIF_flags & TIF_16BIT)) ) { 00292 DirectedScheduleTask(psms->ptiReceiver, psms->ptiSender, FALSE, psms); 00293 } 00294 00295 00296 /* 00297 * return immediately if we are not 16 bit (don't have a pwpi) 00298 */ 00299 if (!(pti->TIF_flags & TIF_16BIT)) { 00300 return FALSE; 00301 } 00302 00303 00304 /* 00305 * Deschedule the current task 00306 */ 00307 if (pti == pwpi->ptiScheduled) { 00308 ExitWowCritSect(pti, pwpi); 00309 if (!pwpi->nTaskLock) { 00310 pwpi->ptiScheduled = NULL; 00311 } 00312 } 00313 UserAssert(pti != pwpi->CSOwningThread); 00314 00315 00316 /* 00317 * If this is wowexec calling on WowWaitForMsgAndEvent 00318 * set up the WakeMask for all messages , and check for wake 00319 * bits set since the last time. Reinsert wowexec, at the end 00320 * of the list so other 16 bit tasks will be scheduled first. 00321 */ 00322 if (pwpi->hEventWowExecClient == hEvent) { 00323 InsertTask(ppi, pti->ptdb); 00324 pti->pcti->fsWakeMask = QS_ALLINPUT | QS_EVENT; 00325 if (pti->pcti->fsChangeBits & pti->pcti->fsWakeMask) { 00326 pti->ptdb->nEvents++; 00327 gpsi->nEvents++; 00328 } 00329 } 00330 00331 00332 bWaitedAtLeastOnce = FALSE; 00333 00334 do { 00335 00336 /* 00337 * If nobody is Active look for the highest priority task with 00338 * some events pending. if MsgWaitForMultiple call don't 00339 * reschedule self 00340 */ 00341 00342 if (pwpi->ptiScheduled == NULL) { 00343 rescan: 00344 if (pwpi->nRecvLock >= pwpi->nSendLock) { 00345 for (ptdb = pwpi->ptdbHead; ptdb; ptdb = ptdb->ptdbNext) { 00346 if (ptdb->nEvents > 0 && 00347 !(hEvent == HEVENT_REMOVEME && ptdb->pti == pti)) { 00348 pwpi->ptiScheduled = ptdb->pti; 00349 break; 00350 } 00351 } 00352 00353 if (bWaitedAtLeastOnce) { 00354 // 00355 // If not first entry into sleep task avoid waiting 00356 // more than needed, if the curr task is now scheduled. 00357 // 00358 if (pwpi->ptiScheduled == pti) { 00359 break; 00360 } 00361 00362 } else { 00363 // 00364 // On the first entry into sleep task input is going 00365 // idle if no tasks are ready to run. Call the idle 00366 // hook if there is one. 00367 // 00368 if (fInputIdle && 00369 pwpi->ptiScheduled == NULL && 00370 IsHooked(pti, WHF_FOREGROUNDIDLE)) { 00371 00372 /* 00373 * Make this the active task so that no other 00374 * task will become active while we're calling 00375 * the hook. 00376 */ 00377 pwpi->ptiScheduled = pti; 00378 xxxCallHook(HC_ACTION, 0, 0, WH_FOREGROUNDIDLE); 00379 00380 /* 00381 * Reset state so that no tasks are active. We 00382 * then need to rescan the task list to see if 00383 * a task was scheduled during the call to the 00384 * hook. Clear the input idle flag to ensure 00385 * that the hook won't be called again if there 00386 * are no tasks ready to run. 00387 */ 00388 pwpi->ptiScheduled = NULL; 00389 fInputIdle = FALSE; 00390 goto rescan; 00391 } 00392 } 00393 } 00394 00395 00396 /* 00397 * If there is a task ready, wake it up. 00398 */ 00399 if (pwpi->ptiScheduled != NULL) { 00400 KeSetEvent(pwpi->ptiScheduled->pEventQueueServer, 00401 EVENT_INCREMENT, 00402 FALSE 00403 ); 00404 00405 /* 00406 * There is no one to wake up, but we may have to wake 00407 * wowexec to service virtual hardware interrupts 00408 */ 00409 } else if (ppi->W32PF_Flags & W32PF_WAKEWOWEXEC) { 00410 if (pwpi->hEventWowExecClient == hEvent) { 00411 pwpi->ptiScheduled = pti; 00412 ppi->W32PF_Flags &= ~W32PF_WAKEWOWEXEC; 00413 InsertTask(ppi, pti->ptdb); 00414 EnterWowCritSect(pti, pwpi); 00415 UserAssert(pti == pwpi->ptiScheduled); 00416 return TRUE; 00417 } else { 00418 KeSetEvent(pwpi->pEventWowExec, EVENT_INCREMENT, FALSE); 00419 } 00420 } else if ((pti->TIF_flags & TIF_SHAREDWOW) && !bWaitedAtLeastOnce) { 00421 if (pwpi->hEventWowExecClient == hEvent) { 00422 /* 00423 * We have to call zzzWakeInputIdle only if this will 00424 * awake WowExec's thread and not other thread. Bug 44060. 00425 */ 00426 zzzWakeInputIdle(pti); // need to DeferWinEventNotify() ?? IANJA ?? 00427 } 00428 } 00429 00430 } else if (pwpi->nTaskLock > 0 && pwpi->ptiScheduled == pti 00431 && pti->ptdb->nEvents > 0) { 00432 KeSetEvent(pwpi->ptiScheduled->pEventQueueServer, 00433 EVENT_INCREMENT, FALSE); 00434 } 00435 /* 00436 * return if we are a 32 bit thread, or if we were called by 00437 * MsgWaitForMultiple to exit the wow scheduler 00438 */ 00439 if (!(pti->TIF_flags & TIF_16BIT)) { 00440 return FALSE; 00441 } else if (hEvent == HEVENT_REMOVEME) { 00442 InsertTask(ppi, pti->ptdb); 00443 KeClearEvent(pti->pEventQueueServer); 00444 return FALSE; 00445 } 00446 00447 if (pti->apEvent == NULL) { 00448 pti->apEvent = UserAllocPoolNonPaged(POLL_EVENT_CNT * sizeof(PKEVENT), TAG_EVENT); 00449 if (pti->apEvent == NULL) 00450 return FALSE; 00451 } 00452 00453 /* 00454 * Wait for input to this thread. 00455 */ 00456 pti->apEvent[IEV_TASK] = pti->pEventQueueServer; 00457 00458 /* 00459 * Add the WowExec, handle for virtual hw interrupts 00460 */ 00461 if (pwpi->hEventWowExecClient == hEvent) { 00462 pti->apEvent[IEV_WOWEXEC] = pwpi->pEventWowExec; 00463 nHandles = 2; 00464 } else { 00465 nHandles = 1; 00466 } 00467 00468 CheckForClientDeath(); 00469 LeaveCrit(); 00470 00471 Status = KeWaitForMultipleObjects(nHandles, 00472 &pti->apEvent[IEV_TASK], 00473 WaitAny, 00474 WrUserRequest, 00475 UserMode, 00476 TRUE, 00477 NULL, 00478 NULL); 00479 00480 CheckForClientDeath(); 00481 00482 EnterCrit(); 00483 00484 bWaitedAtLeastOnce = TRUE; 00485 00486 // remember if we woke up for wowexec 00487 if (Status == STATUS_WAIT_1) { 00488 ppi->W32PF_Flags |= W32PF_WAKEWOWEXEC; 00489 } else if (Status == STATUS_USER_APC) { 00490 00491 /* 00492 * An alert was received. This should only occur when the 00493 * thread has been terminated. 00494 * ClientDeliverUserApc() delivers User-mode APCs by calling back 00495 * to the client and immediately returning without doing anything: 00496 * KeUserModeCallback will automatically deliver any pending APCs. 00497 */ 00498 UserAssert(PsIsThreadTerminating(PsGetCurrentThread())); 00499 ClientDeliverUserApc(); 00500 } 00501 00502 } while (pwpi->ptiScheduled != pti); 00503 00504 00505 /* 00506 * We are the Active Task, reduce number of Events 00507 * Place ourselves at the far end of tasks in the same priority 00508 * so that next time we sleep someone else will run. 00509 */ 00510 pti->ptdb->nEvents--; 00511 gpsi->nEvents--; 00512 UserAssert(gpsi->nEvents >= 0); 00513 00514 InsertTask(ppi, pti->ptdb); 00515 00516 ppi->W32PF_Flags &= ~W32PF_WAKEWOWEXEC; 00517 00518 EnterWowCritSect(pti, pwpi); 00519 UserAssert(pti == pwpi->ptiScheduled); 00520 00521 00522 00523 return FALSE; 00524 } 00525 00526 00527 00528 /***************************************************************************\ 00529 * xxxUserYield 00530 * 00531 * Does exactly what Win3.1 UserYield does. 00532 * 00533 * History: 00534 * 10-19-92 Scottlu Created. 00535 \***************************************************************************/ 00536 00537 BOOL xxxUserYield( 00538 PTHREADINFO pti) 00539 { 00540 PPROCESSINFO ppi = pti->ppi; 00541 00542 /* 00543 * Deal with any pending messages. Only call it this first time if 00544 * this is the current running 16 bit app. In the case when starting 00545 * up a 16 bit app, the starter calls UserYield() to yield to the new 00546 * task, but at this time ppi->ptiScheduled is set to the new task. 00547 * Receiving messages at this point would be bad! 00548 */ 00549 if (pti->TIF_flags & TIF_16BIT) { 00550 if (pti == ppi->pwpi->ptiScheduled) { 00551 xxxReceiveMessages(pti); 00552 } 00553 } else { 00554 xxxReceiveMessages(pti); 00555 } 00556 00557 /* 00558 * If we are a 16 bit task 00559 * Mark our task so it comes back some time. Also, remove it and 00560 * re-add it to the list so that we are the last task of our priority 00561 * to run. 00562 */ 00563 if ((pti->TIF_flags & TIF_16BIT) && (pti->ptdb != NULL)) { 00564 if (pti->ptdb->nEvents == 0) { 00565 pti->ptdb->nEvents++; 00566 gpsi->nEvents++; 00567 } 00568 InsertTask(ppi, pti->ptdb); 00569 00570 /* 00571 * Sleep. Return right away if there are no higher priority tasks 00572 * in need of running. 00573 */ 00574 xxxSleepTask(TRUE, NULL); 00575 00576 /* 00577 * Deal with any that arrived since we weren't executing. 00578 */ 00579 xxxReceiveMessages(pti); 00580 } 00581 00582 00583 return TRUE; 00584 } 00585 00586 00587 /***************************************************************************\ 00588 * DirectedScheduleTask 00589 * 00590 * History: 00591 * 25-Jun-1992 mikeke Created. 00592 \***************************************************************************/ 00593 00594 VOID DirectedScheduleTask( 00595 PTHREADINFO ptiOld, 00596 PTHREADINFO ptiNew, 00597 BOOL bSendMsg, 00598 PSMS psms 00599 ) 00600 { 00601 PWOWPROCESSINFO pwpiOld; 00602 PWOWPROCESSINFO pwpiNew; 00603 00604 CheckCritIn(); 00605 00606 pwpiOld = ptiOld->ppi->pwpi; 00607 pwpiNew = ptiNew->ppi->pwpi; 00608 00609 00610 /* 00611 * If old task is 16 bit, reinsert the task in its wow scheduler list 00612 * so that it is lowest in priority. Note that ptiOld is always the 00613 * same as pwpiOld->ptiScheduled except when called from ReceiverDied. 00614 */ 00615 if (ptiOld->TIF_flags & TIF_16BIT) { 00616 00617 if (pwpiOld->ptiScheduled == ptiOld) { 00618 ptiOld->ptdb->nEvents++; 00619 gpsi->nEvents++; 00620 InsertTask(ptiOld->ppi, ptiOld->ptdb); 00621 } 00622 00623 00624 // Update the Send\Recv counts for interprocess scheduling in SleepTask 00625 00626 if (pwpiOld != pwpiNew || !(ptiNew->TIF_flags & TIF_16BIT)) { 00627 if (bSendMsg) { 00628 pwpiOld->nSendLock++; 00629 psms->flags |= SMF_WOWSEND; 00630 } 00631 else if (pwpiOld->nRecvLock && psms->flags & SMF_WOWRECEIVE) { 00632 pwpiOld->nRecvLock--; 00633 psms->flags &= ~SMF_WOWRECEIVE; 00634 } 00635 } 00636 00637 } 00638 00639 00640 /* 00641 * If the new task is 16 bit, reinsert into the wow scheduler list 00642 * so that it will run, if its a sendmsg raise priority of the receiver. 00643 * If its a reply and the sender is waiting for this psms or the sender 00644 * has a message to reply to raise priority of the sender. 00645 */ 00646 if (ptiNew->TIF_flags & TIF_16BIT) { 00647 BOOL bRaisePriority; 00648 00649 ptiNew->ptdb->nEvents++; 00650 gpsi->nEvents++; 00651 bRaisePriority = bSendMsg || psms == ptiNew->psmsSent; 00652 00653 if (bRaisePriority) { 00654 ptiNew->ptdb->nPriority--; 00655 } 00656 00657 InsertTask(ptiNew->ppi, ptiNew->ptdb); 00658 00659 if (bRaisePriority) { 00660 ptiNew->ptdb->nPriority++; 00661 WakeWowTask(ptiNew); 00662 } 00663 00664 00665 // Update the Send\Recv counts for interprocess scheduling in SleepTask 00666 00667 if (pwpiOld != pwpiNew || !(ptiOld->TIF_flags & TIF_16BIT)) { 00668 if (bSendMsg) { 00669 pwpiNew->nRecvLock++; 00670 psms->flags |= SMF_WOWRECEIVE; 00671 } 00672 else if (pwpiNew->nSendLock && psms->flags & SMF_WOWSEND) { 00673 pwpiNew->nSendLock--; 00674 psms->flags &= ~SMF_WOWSEND; 00675 } 00676 } 00677 00678 } 00679 } 00680 00681 00682 00683 00684 /***************************************************************************\ 00685 * xxxDirectedYield 00686 * 00687 * History: 00688 * 09-17-92 JimA Created. 00689 \***************************************************************************/ 00690 00691 void xxxDirectedYield( 00692 DWORD dwThreadId) 00693 { 00694 PTHREADINFO ptiOld; 00695 PTHREADINFO ptiNew; 00696 00697 CheckCritIn(); 00698 00699 ptiOld = PtiCurrent(); 00700 if (!(ptiOld->TIF_flags & TIF_16BIT) || !ptiOld->ppi->pwpi) { 00701 RIPMSG0(RIP_ERROR, "DirectedYield called from 32 bit thread!"); 00702 return; 00703 } 00704 00705 /* 00706 * If the old task is 16 bit, reinsert the task in its wow 00707 * scheduler list so that it is lowest in priority. 00708 */ 00709 ptiOld->ptdb->nEvents++; 00710 gpsi->nEvents++; 00711 InsertTask(ptiOld->ppi, ptiOld->ptdb); 00712 00713 /* 00714 * -1 supports Win 3.1 OldYield mechanics 00715 */ 00716 if (dwThreadId != DY_OLDYIELD) { 00717 00718 ptiNew = PtiFromThreadId(dwThreadId); 00719 if (ptiNew == NULL) 00720 return; 00721 00722 if (ptiNew->TIF_flags & TIF_16BIT) { 00723 ptiNew->ptdb->nEvents++; 00724 gpsi->nEvents++; 00725 ptiNew->ptdb->nPriority--; 00726 InsertTask(ptiNew->ppi, ptiNew->ptdb); 00727 ptiNew->ptdb->nPriority++; 00728 } 00729 } 00730 00731 xxxSleepTask(TRUE, NULL); 00732 } 00733 00734 00735 /***************************************************************************\ 00736 * CurrentTaskLock 00737 * 00738 * Lock the current 16 bit task into the 16 bit scheduler 00739 * 00740 * Parameter: 00741 * hlck if NULL, lock the current 16 bit task and return a lock handle 00742 * if valid lock handle, unlock the current task 00743 * 00744 * History: 00745 * 13-Apr-1992 jonpa Created. 00746 \***************************************************************************/ 00747 #if 0 /* WOW is not using this but they might some day */ 00748 DWORD CurrentTaskLock( 00749 DWORD hlck) 00750 { 00751 PWOWPROCESSINFO pwpi = PpiCurrent()->pwpi; 00752 00753 if (!pwpi) 00754 return 0; 00755 00756 if (hlck == 0) { 00757 pwpi->nTaskLock++; 00758 return ~(DWORD)pwpi->ptiScheduled->ptdb; 00759 } else if ((~hlck) == (DWORD)pwpi->ptiScheduled->ptdb) { 00760 pwpi->nTaskLock--; 00761 } 00762 00763 return 0; 00764 } 00765 #endif

Generated on Sat May 15 19:41:57 2004 for test by doxygen 1.3.7