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

badapp.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: badapp.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 \***************************************************************************/ 00007 00008 #include "precomp.h" 00009 #pragma hdrstop 00010 00011 BOOL G_bFirstCount = TRUE; 00012 BADAPP G_UserBadApp; 00013 00014 //#define BADAPPTRACE 00016 //note that the bad app fix is made up of changes to the following files 00017 //windows\user\client - client.c cltxt.h csend.c clinit.c globals.h 00018 // \inc - user.h cf.h cf1.h 00019 // \server - server.c input.c queue.c focusact.c 00020 // \gdi\inc - csrgdi.h 00021 //windows\base\client\citrix - compatfl.c compatfl.h 00022 //mvdm\wow32 - wkman.c 00023 //sdk\inc - ntpsapi.h 00024 // 00025 //the mechanism was moved from the server to client and changed to a sleep 00026 // see server.c for the registry stuff which is in control\\citrix 00027 // the pti->cSpins and teb->user32reserved0 fields were changed 00028 // and tif_spinning and pif_forcebackgroundpriority and cspinbackground 00029 // were removed to more easily detect a sync problem with new source 00030 //Values can be stored in the registry for each app (under 00031 // machine\software\citrix\compatibility\applications\xxx (where xxx is the 00032 // application name). For win32 apps, when user32.dll is loaded it 00033 // initializes the values in the G_UserBadApp structure, and for Win16 apps 00034 // the values are stored in the Teb by wow32 when the app is loaded. If 00035 // neither of these values are filled in, this routine will use the default 00036 // system values. 00037 00038 00039 /************************************************************** 00040 * CtxBadAppDelay 00041 * 00042 * If counttype=0 then call is due to peek. else was a yield 00043 * we don't use the difference right now 00044 * the delaycount is determined based on G_bFirstCount 00045 * If count > delaycount 00046 * then reset the count 00047 * Then sleep for BadAppTimeDelay milliseconds 00048 * 00049 * G_bFirstCount reset to TRUE if get message from PeekMessage or GetMessage 00050 * or in this routine if pti->cSpins == 0 00051 * 00052 * Returns the amount of milliseconds delayed 00053 */ 00054 VOID CtxBadAppDelay(ULONG counttype) 00055 { 00056 ULONG delaycount; 00057 PCLIENTINFO pci; 00058 PTEB pTeb; 00059 LARGE_INTEGER BadAppDelay; 00060 00061 pci = GetClientInfo(); 00062 pTeb = NtCurrentTeb(); 00063 if ( (pci != NULL) && ((pci->CitrixcSpins) == 0) ) { 00064 G_bFirstCount = TRUE; 00065 } 00066 00067 if (G_UserBadApp.BadAppFlags & CITRIX_COMPAT_BADAPPVALID) { 00068 if (G_bFirstCount) { 00069 delaycount = G_UserBadApp.BadAppFirstCount; 00070 } else { 00071 delaycount = G_UserBadApp.BadAppNthCount; 00072 } 00073 BadAppDelay = G_UserBadApp.BadAppTimeDelay; 00074 } else if (pTeb->CtxCompatFlags & CITRIX_COMPAT_BADAPPVALID) { 00075 if (G_bFirstCount) { 00076 delaycount = pTeb->BadAppFirstCount; 00077 } else { 00078 delaycount = pTeb->BadAppNthCount; 00079 } 00080 BadAppDelay = pTeb->BadAppTimeDelay; 00081 } else { 00082 if (G_bFirstCount) { 00083 delaycount = gpsi->BadAppFirstCount; 00084 } 00085 else delaycount = gpsi->BadAppNthCount; 00086 BadAppDelay = gpsi->BadAppTimeDelay; 00087 } 00088 00089 if ( (pTeb->CitrixTEBcSpins) > delaycount ) { 00090 (pTeb->CitrixTEBcSpins) = 0; 00091 00092 #ifdef BADAPPTRACE 00093 if (counttype) { 00094 DbgPrint("j.k. CtxBadAppDelay YIELD, bFirstCount=%u\n",(ULONG) bFirstCount); 00095 } 00096 else DbgPrint("j.k. CtxBadAppDelay PEEK, bFirstCount=%u\n",(ULONG) bFirstCount); 00097 #endif 00098 00099 G_bFirstCount = FALSE; 00100 NtDelayExecution( 00101 FALSE, 00102 &BadAppDelay); 00103 } 00104 return; 00105 UNREFERENCED_PARAMETER(counttype); 00106 } 00107 00108 /* 00109 * This is the Citrix version of NtUserYieldTask() that implements the Bad App processing 00110 * 00111 */ 00112 BOOL 00113 CtxUserYieldTask( VOID ) 00114 { 00115 ULONG cSpins; 00116 PCLIENTINFO pci; 00117 BOOL Result; 00118 00119 //every yield is bad news 00120 //server side increments so if not reset should move our count 00121 pci = GetClientInfo(); 00122 if (pci != NULL) { 00123 cSpins = pci->CitrixcSpins; 00124 } 00125 00126 Result = NtUserYieldTask(); 00127 00128 if ( pci != NULL) { 00129 if (cSpins >= pci->CitrixcSpins) { 00130 //in this case the server side reset cspins so we reset our count 00131 (NtCurrentTeb()->CitrixTEBcSpins) = pci->CitrixcSpins; 00132 } 00133 else { 00134 (NtCurrentTeb()->CitrixTEBcSpins) += pci->CitrixcSpins - cSpins; 00135 CtxBadAppDelay(1); //show yield. 00136 } 00137 } 00138 00139 return( Result ); 00140 } 00141 00142 /* 00143 * This is the Citrix version of NtUserWaitMessage() that implements the Bad App processing 00144 * 00145 */ 00146 BOOL 00147 CtxUserWaitMessage( VOID ) 00148 { 00149 //since waiting, we can reset to firstcount 00150 G_bFirstCount = TRUE; 00151 00152 return ( NtUserWaitMessage() ); 00153 }

Generated on Sat May 15 19:39:18 2004 for test by doxygen 1.3.7