| 1172 | |
| 1173 | |
| 1174 | ResultType Script::AutoExecSection() |
| 1175 | // Returns FAIL if can't run due to critical error. Otherwise returns OK. |
| 1176 | { |
| 1177 | // Now that g_MaxThreadsTotal has been permanently set by the processing of script directives like |
| 1178 | // #MaxThreads, an appropriately sized array can be allocated: |
| 1179 | if ( !(g_array = (global_struct *)malloc((g_MaxThreadsTotal+TOTAL_ADDITIONAL_THREADS) * sizeof(global_struct))) ) |
| 1180 | return FAIL; // Due to rarity, just abort. It wouldn't be safe to run ExitApp() due to possibility of an OnExit function. |
| 1181 | CopyMemory(g_array, g, sizeof(global_struct)); // Copy the temporary/startup "g" into array[0]. |
| 1182 | g = g_array; // Must be done after above. |
| 1183 | |
| 1184 | // v2: Ensure the Hotkey function defaults to no criterion rather than the last #HotIf WinActive/Exist(). Alternatively we |
| 1185 | // could replace CopyMemory() above with global_init(), but it would need to be changed back if ever we |
| 1186 | // want a directive to affect the default settings. |
| 1187 | g->HotCriterion = NULL; |
| 1188 | |
| 1189 | // Must be done before InitClasses(), otherwise destroying a Gui in a class constructor |
| 1190 | // would terminate the script: |
| 1191 | ++g_nThreads; |
| 1192 | |
| 1193 | // v1.0.48: Due to switching from SET_UNINTERRUPTIBLE_TIMER to IsInterruptible(): |
| 1194 | // In spite of the comments in IsInterruptible(), periodically have a timer call IsInterruptible() due to |
| 1195 | // the following scenario: |
| 1196 | // - Interrupt timeout is 60 seconds (or 60 milliseconds for that matter). |
| 1197 | // - For some reason IsInterrupt() isn't called for 24+ hours even though there is a current/active thread. |
| 1198 | // - RefreshInterruptibility() fires at 23 hours and marks the thread interruptible. |
| 1199 | // - Sometime after that, one of the following happens: |
| 1200 | // Computer is suspended/hibernated and stays that way for 50+ days. |
| 1201 | // IsInterrupt() is never called (except by RefreshInterruptibility()) for 50+ days. |
| 1202 | // (above is currently unlikely because MSG_FILTER_MAX calls IsInterruptible()) |
| 1203 | // In either case, RefreshInterruptibility() has prevented the uninterruptibility duration from being |
| 1204 | // wrongly extended by up to 100% of g_script.mUninterruptibleTime. This isn't a big deal if |
| 1205 | // g_script.mUninterruptibleTime is low (like it almost always is); but if it's fairly large, say an hour, |
| 1206 | // this can prevent an unwanted extension of up to 1 hour. |
| 1207 | // Although any call frequency less than 49.7 days should work, currently calling once per 23 hours |
| 1208 | // in case any older operating systems have a SetTimer() limit of less than 0x7FFFFFFF (and also to make |
| 1209 | // it less likely that a long suspend/hibernate would cause the above issue). The following was |
| 1210 | // actually tested on Windows XP and a message does indeed arrive 23 hours after the script starts. |
| 1211 | SetTimer(g_hWnd, TIMER_ID_REFRESH_INTERRUPTIBILITY, 23*60*60*1000, RefreshInterruptibility); // 3rd param must not exceed 0x7FFFFFFF (2147483647; 24.8 days). |
| 1212 | |
| 1213 | ResultType ExecUntil_result; |
| 1214 | |
| 1215 | if (!mFirstLine) // In case it's ever possible to be empty. |
| 1216 | ExecUntil_result = OK; |
| 1217 | // And continue on to do normal exit routine so that the right ExitCode is returned by the program. |
| 1218 | else |
| 1219 | { |
| 1220 | SET_AUTOEXEC_TIMER(100); // Currently this only marks the auto-execute thread as uninterruptible for the time indicated. |
| 1221 | mAutoExecSectionIsRunning = true; |
| 1222 | |
| 1223 | // v1.0.25: This is now done here, closer to the actual execution of the first line in the script, |
| 1224 | // to avoid an unnecessary Sleep(10) that would otherwise occur in ExecUntil: |
| 1225 | mLastPeekTime = GetTickCount(); |
| 1226 | |
| 1227 | DEBUGGER_STACK_PUSH(_T("Auto-execute")) |
| 1228 | ExecUntil_result = mFirstLine->ExecUntil(UNTIL_RETURN); // Might never return (e.g. infinite loop or ExitApp). |
| 1229 | DEBUGGER_STACK_POP() |
| 1230 | |
| 1231 | mAutoExecSectionIsRunning = false; |
no test coverage detected