| 1490 | |
| 1491 | |
| 1492 | bool CheckScriptTimers() |
| 1493 | // Returns true if it launched at least one thread, and false otherwise. |
| 1494 | // It's best to call this function only directly from MsgSleep() or when there is an instance of |
| 1495 | // MsgSleep() closer on the call stack than the nearest dialog's message pump (e.g. MsgBox). |
| 1496 | // This is because threads some events might get queued up for our thread during the execution |
| 1497 | // of the timer subroutines here. When those subroutines finish, if we return directly to a dialog's |
| 1498 | // message pump, and such pending messages might be discarded or mishandled. |
| 1499 | // Caller should already have checked the value of g_script.mTimerEnabledCount to ensure it's |
| 1500 | // greater than zero, since we don't check that here (for performance). |
| 1501 | // This function will go through the list of timed subroutines only once and then return to its caller. |
| 1502 | // It does it only once so that it won't keep a thread beneath it permanently suspended if the sum |
| 1503 | // total of all timer durations is too large to be run at their specified frequencies. |
| 1504 | // This function is allowed to be called recursively, which handles certain situations better: |
| 1505 | // 1) A hotkey subroutine interrupted and "buried" one of the timer subroutines in the stack. |
| 1506 | // In this case, we don't want all the timers blocked just because that one is, so recursive |
| 1507 | // calls from ExecUntil() are allowed, and they might discover other timers to run. |
| 1508 | // 2) If the script is idle but one of the timers winds up taking a long time to execute (perhaps |
| 1509 | // it gets stuck in a long WinWait), we want a recursive call (from MsgSleep() in this example) |
| 1510 | // to launch any other enabled timers concurrently with the first, so that they're not neglected |
| 1511 | // just because one of the timers happens to be long-running. |
| 1512 | // Of course, it's up to the user to design timers so that they don't cause problems when they |
| 1513 | // interrupted hotkey subroutines, or when they themselves are interrupted by hotkey subroutines |
| 1514 | // or other timer subroutines. |
| 1515 | { |
| 1516 | // When the following is true, such as during a SendKeys() operation, it seems best not to launch any |
| 1517 | // new timed subroutines. The reasons for this are similar to the reasons for not allowing hotkeys |
| 1518 | // to fire during such times. Those reasons are discussed in other comments. In addition, |
| 1519 | // it seems best as a policy not to allow timed subroutines to run while the script's current |
| 1520 | // quasi-thread is paused. Doing so would make the tray icon flicker (were it even updated below, |
| 1521 | // which it currently isn't) and in any case is probably not what the user would want. Most of the |
| 1522 | // time, the user would want all timed subroutines stopped while the current thread is paused. |
| 1523 | // And even if this weren't true, the confusion caused by the subroutines still running even when |
| 1524 | // the current thread is paused isn't worth defaulting to the opposite approach. In the future, |
| 1525 | // and if there's demand, perhaps a config option can added that allows a different default behavior. |
| 1526 | // UPDATE: It seems slightly better (more consistent) to disallow all timed subroutines whenever |
| 1527 | // there is even one paused thread anywhere in the "stack". |
| 1528 | // v1.0.48: Since g_IdleIsPaused was removed (to simplify a lot of things), g_nPausedThreads now |
| 1529 | // counts the idle thread if it's paused. Also, to avoid array overflow, g_MaxThreadsTotal must not |
| 1530 | // be exceeded except where otherwise documented. |
| 1531 | // v2.0: g->AllowTimers is ignored when !g_nThreads so that its value can be retained for use as |
| 1532 | // the default for new threads, after the auto-execute thread finishes. |
| 1533 | if (g_nPausedThreads > 0 || (!g->AllowTimers && g_nThreads) || g_nThreads >= g_MaxThreadsTotal || !IsInterruptible()) // See above. |
| 1534 | return false; |
| 1535 | |
| 1536 | ScriptTimer *ptimer, *next_timer; |
| 1537 | BOOL at_least_one_timer_launched; |
| 1538 | DWORD tick_start; |
| 1539 | |
| 1540 | // Note: It seems inconsequential if a subroutine that the below loop executes causes a |
| 1541 | // new timer to be added to the linked list while the loop is still enumerating the timers. |
| 1542 | |
| 1543 | for (at_least_one_timer_launched = FALSE, ptimer = g_script.mFirstTimer |
| 1544 | ; ptimer != NULL |
| 1545 | ; ptimer = next_timer) |
| 1546 | { |
| 1547 | ScriptTimer &timer = *ptimer; // For performance and convenience. |
| 1548 | if (!timer.mEnabled || timer.mExistingThreads > 0 || timer.mPriority < g->Priority) // thread priorities |
| 1549 | { |
nothing calls this directly
no test coverage detected