How long does critical last?

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
Coiler
Posts: 114
Joined: 29 Nov 2020, 09:06

How long does critical last?

Post by Coiler » 31 Dec 2020, 22:57

Does marking a thread critical last throughout an entire thread, regardless of function calls, function returns, etc? Or does every single function / code block need to specify itself critical?

I have a critical placed at the beginning of my first hotkey thread (Ctrl), but it is still being interrupted by my second hotkey event/thread (*f), before the first has a chance to setup states correctly. There are several functions being called in the first, and it looks like it can take up to 100 ms to get to the point where I want the next hotkey to interrupt it.

But I can't seem to get the second event to wait for the first to finish, even if I put critical 10000 at the top of my first thread. Can anyone help me understand why? I'm using V2, but hopefully that is irrelevant.

EDIT: After messing around a bit more and debugging some stuff, it looks like using critical 10000 actually does work as expected. Does anyone know why I would need to specify a specific amount of time? I thought critical "on" would mark a thread as NEVER interruptible? If not, does that mean critical "on" or simply critical by itself just increases the time from 5ms to 16ms?

Thanks!
Last edited by BoBo on 01 Jan 2021, 08:21, edited 2 times in total.
Reason: Moved to 'AutoHotkey v2 Help'.

User avatar
mikeyww
Posts: 26951
Joined: 09 Sep 2014, 18:38

Re: How long does critical last?

Post by mikeyww » 01 Jan 2021, 07:51

As far as I know, the v1 syntax would be Critical or Critical, On.

AHK has so many native functions that it would not seem to make sense to have them ignore Critical (so I imagine that they do not-- but this is also testable).
The current thread is defined as the flow of execution invoked by the most recent event; examples include hotkeys, SetTimer subroutines, custom menu items, and GUI events. The current thread can be executing commands within its own subroutine or within other subroutines called by that subroutine.
If you have an example of a critical thread that is interrupted, you could post it for readers to review.

User avatar
Coiler
Posts: 114
Joined: 29 Nov 2020, 09:06

Re: How long does critical last?

Post by Coiler » 01 Jan 2021, 10:10

As far as I can tell, the critical keyword only lasts for 16 milliseconds unless you specify a longer time. The documentation makes it sound like not specifying a time sets it permanently, but I don't think that is the case.

HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: How long does critical last?

Post by HotKeyIt » 01 Jan 2021, 10:16

Yes, the documentation says it sets critical permanently which means that messages are checked every 16 ms instead of 5 ms.
Specifying a number changes that time, so Critical, 60000 will check messages once in a minute, so thread will not be interrupted for 1 minute!
Specifying a positive number as the first parameter (e.g. Critical 30) turns on Critical but also changes the number of milliseconds between checks of the internal message queue. If unspecified, messages are checked every 16 milliseconds while Critical is On, and every 5 ms while Critical is Off. Increasing the interval postpones the arrival of messages/events, which gives the current thread more time to finish. This reduces the possibility that certain OnMessage() and GUI events will be lost due to "thread already running". However, commands that wait such as Sleep and WinWait will check messages regardless of this setting (a workaround is DllCall("Sleep", "UInt", 500)).

User avatar
mikeyww
Posts: 26951
Joined: 09 Sep 2014, 18:38

Re: How long does critical last?

Post by mikeyww » 01 Jan 2021, 10:23

Thanks, @HotKeyIt!

User avatar
Coiler
Posts: 114
Joined: 29 Nov 2020, 09:06

Re: How long does critical last?

Post by Coiler » 01 Jan 2021, 11:43

I ended up having to use a very large critical time to get the behavior I wanted. But if you do this and use KeyWait, make sure to turn critical off before waiting on the key. I assumed KeyWait would automatically turn critical off, but it does not. Without manually turning it off, I receive a ton of "auto-repeat" events for my hotkey after its thread exits.

Is it possible to turn off interruptions without stopping the message queue? I want AHK to notice and process hotkeys in the background as normal, but I just don't want it to interrupt the thread execution until it finishes. Maybe that's not possible.

HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: How long does critical last?

Post by HotKeyIt » 01 Jan 2021, 13:39

What is interrupting your thread if not hotkey?
In case of timer, you can use Thread "NoTimers", 1, see https://lexikos.github.io/v2/docs/commands/Thread.htm

User avatar
Coiler
Posts: 114
Joined: 29 Nov 2020, 09:06

Re: How long does critical last?

Post by Coiler » 01 Jan 2021, 15:17

HotKeyIt wrote:
01 Jan 2021, 13:39
What is interrupting your thread if not hotkey?
In case of timer, you can use Thread "NoTimers", 1, see https://lexikos.github.io/v2/docs/commands/Thread.htm
It is just hotkeys. Basically, my script sets states when certain keys are pressed, and those states change the behavior of other keys until they are released or time out. These state-changing keys need to set things up BEFORE the next key executes, or it won't work correctly.

An example would be Ctrl+F. If the user presses Ctrl, F, then releases both, all before the script even notices, the script would send one after the other, without allowing the first to finish. Inside my logic for Ctrl, there would be something like MyState := CTRLSTATE, then the F key would see that state turned on, and react differently.

My real script creates custom modifiers as part of the user's key map. But Ctrl makes a decent example.

Edit: what I meant by "process hotkeys in the background" is that I want AHK to notice the "auto repeat" events of a key while it is held and ignore them because that key already has a thread running. Otherwise, without "processing them", the events all build up until I unlock the critical thread. I guess what I was hoping for was to allow AHK to notice events, and "buffer" hotkeys until my thread finishes. But what really happens is that AHK doesn't even seem to notice the events until my thread finishes.


User avatar
Simon Belmont
Posts: 19
Joined: 03 Dec 2020, 00:14

Re: How long does critical last?

Post by Simon Belmont » 24 Jan 2022, 13:42

If Critical or Critical, On occurs outside of a HotKey's thread or { }s, it will remain true until Critical, Off occurs.

If Critical or Critical, On occurs within a HotKey's thread or { }, it will remain true until either Critical, Off occurs or the thread ends.

Code: Select all

A::
Critical, On	; will remain true until,
{
	Send, {I}{Space}{a}{m}{Space}{h}{i}{g}{h}{l}{y}{Space}{[}{i}{]}{c}{r}{i}{t}{i}{c}{a}{l}{[}{/}{i}{]}{Space}{o}{f}{Space}{A}{H}{K}{'}{s}{Space}{b}{u}{f}{f}{e}{r}{.}
	Return		; this,
}				; this,
Return			; or this, occurs.

Post Reply

Return to “Ask for Help (v2)”