std.Thread.getName/setName: rework windows implementation #10003
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
So, the current implementation of
Thread.getName
andThread.setName
on Win32 uses theGetThreadDescription
andSetThreadDescription
APIs respectively. The problem with this is sort of documented in the source:zig/lib/std/Thread.zig
Lines 88 to 93 in a3c9bfe
However, it hard links to
kernel32.dll
and the function was not in there until after W10 1607, it was previously acquired by querying the symbol fromkernelbase.dll
at runtime. Putting loader code for a shared object in the standard library is pretty ugly though, and doesn't solve properly linking to it in cases where it's available. Thankfully as with a lot of things in Win32 you can ditch this terrible null-terminator-using API entirely, and just useNt*
functions to get the job done correctly.This PR changes the functions to use the
Nt(Get/Set)InformationThread
APIs to query and set the name, and since the higher level APIs are just a wrapper for these, it's fully compatible with them, sans extra allocation for query, global error code set, and the need to check for compatibility at all because on older systems it simply just returns a status saying it's not implemented. Great!Note: These don't have anything to do with the new implementation, these were present in the previous one too, but if you do
setName("")
thengetName()
returnsnull
because NT makes no distinction between an unset thread name and an empty thread name. The other problem is if that someone else usesNt*
functions to make a thread name bigger than the current limit in std, it'll yielderror.Unexpected
, or potentially cause a very ugly assertion failure inutf16leToUtf8
even (unsure), the limit on the thread name is 64KiB (c_ushort
), not 32B like it currently says. Maybe something related to these issues should be put in this PR too, but it could be out of scope, especially since the latter only happens if raw Win32 (or FFI) is mixed with std.