v2.1: Added A_ThreadId and a thread id parameter to Exit()#339
v2.1: Added A_ThreadId and a thread id parameter to Exit()#339Descolada wants to merge 5 commits intoAutoHotkey:alphafrom
Conversation
|
This might be extremely handy in certain situations if implemented. In this situation i need to
This new Also if this could be extended for pausing a thread that would also be amazing for similar situations! All in all I am all for having some sort of pseudo thread identification / manipulation to handle certain UI actions that right now need some clunky workarounds. |
|
The naming is certainly tragic. In other languages this might be called an execution context or a task. I wonder if it's too late to change it. |
A_ThreadIdA_ThreadIdreturns a nearly unique id for the running pseudo-thread. It can be used to differentiate pseudo-threads (eg by using a Map object), or withExit()to terminate a specific thread (see down below for explanations). The auto-execute section id is always 65537 ((1 << 16) | 1).Implementation:
A_ThreadIdis a 64-bit integer, where the lower 16 bits store the number of active threads, and the next 32 bits is the number of total threads created at the moment of the current pseudo-thread creation. Upmost 16 bits are reserved for future applications.64 bits was chosen over 32 bits because it drastically increases the chance that the id is unique: with 32 bits I would've split it into 20 and 12 bits, which would overflow after ~1 million pseudo-threads, a number which is feasibly reached. Additionally the bit arithmetic looked uglier:
A_ThisThread & 0xFFFinstead ofA_ThisThread & 0xFFFF. Furthermore, as a 32-bit integer overflow is highly unlikely during the lifetime of a script, it can be used to differentiate newer threads from older ones.Exit [ExitCode, ThreadId]Additionally this PR modifies
Exit [ExitCode]toExit [ExitCode, ThreadId]and adds a return value to it.ThreadIdmay be either a specific thread id returned byA_ThisThread, or an index number in the current stack of pseudo-threads. For example,Exit(, 1)marks the first (oldest) pseudo-thread in the stack for termination;Exit(, (A_ThisThread & 0xFFFF) - 1marks the underlying thread;Exit(, (1 << 16) | 1)marks the auto-execute section. A thread marked for termination will exit once the stack unwinds to it, the thread resumes execution, and starts executing the next line. This means that if it was interrupted during a chained expression, then the last parts of the expression will still execute. Such behavior was chosen to limit the number of checks for whether to stop thread execution, and gives a bit more flexibility to the user: if some action should unconditionally be executed after another, then the user can chain it in an expression instead of a new line to prevent another thread from stopping it.The behavior of
Exit [ExitCode]is almost unchanged and causes the running thread to immediately exit, handling __delete and finally afterwards if needed. One exception is that callingDllCall(CallbackCreate((*) => Exit(), "F"))will now cause the thread which calledDllCallto exit, because Fast mode doesn't create a new thread.Exitreturns the terminated thread id, or 0 if no thread was terminated.Some test cases:
1.