gh-59705: Implement _thread.set_name() on Windows#128675
gh-59705: Implement _thread.set_name() on Windows#128675vstinner merged 7 commits intopython:mainfrom
Conversation
Implement set_name() with SetThreadDescription() and _get_name() with GetThreadDescription(). If SetThreadDescription() or GetThreadDescription() is not available in kernelbase.dll, delete the method when the _thread module is imported. Truncate the thread name to an arbitrary limit of 64 characters. set_name() raises ValueError if the name contains an embedded null character. Co-authored-by: Eryk Sun <eryksun@gmail.com>
|
Code based on @eryksun's code: #59705 (comment). Differences with his code:
I copied this limit from @eryksun's code. Maybe it can be extended to 32766 characters?
If it's a blocker issue, I can write the code differently to truncate to the first null character instead. |
I misunderstood the code, in fact, the name is truncated at the first null character (ValueError is not raised): same behavior than Linux/macOS/FreeBSD/etc. |
|
The alternative to The Process Explorer tool doesn't show thread names. |
|
I'm not familiar with Windows API, but this looks right to me. A review from @python/windows-team would be great though :) (Specifically: this is a best-effort attempt to add info to aid debugging or understanding what's going on in a system: we want to as much as we reasonably can to the OS, but it's OK drop part of the name or not set it at all, and errors should be discarded since the user didn't really ask for this. And |
|
I plan to merge this change at the beginning of next week (January 20th). |
|
I fixed the truncation for surrogate pairs and I added tests with non-BMP characters (creating surrogate pairs on Windows). |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
I am not a Windows expert, but the code LGTM. Although I am not sure that we should set such small artificial limit.
There are also some issues in tests.
Ok, I increased the limit from 64 to 32766 characters. |
|
Thanks for the reviews. I enabled auto-merge. |
|
|
||
| #ifdef MS_WINDOWS | ||
| HMODULE kernelbase = GetModuleHandleW(L"kernelbase.dll"); | ||
| if (kernelbase != NULL) { |
There was a problem hiding this comment.
If this check fails, we likely want to report a system error since everything is broken, but at least we should call DelAttr to remove the functions, since the function pointers will be null.
There was a problem hiding this comment.
set_name()/_get_name() is a minor feature of the _thread module, I would prefer to not prevent to import _thread if loading kernelbase.dll fails for whatever reason.
but at least we should call DelAttr to remove the functions, since the function pointers will be null.
Oops, my code was wrong. Fixed.
PC/pyconfig.h.in
Outdated
|
|
||
| // Truncate the thread name to 64 characters. The OS limit is 32766 wide | ||
| // characters, but long names aren't of practical use. | ||
| #define PYTHREAD_NAME_MAXLEN 64 |
There was a problem hiding this comment.
There's no reason for us to artificially limit this at all, but I'd rather be much closer to the real limit than this. "Aren't of practical use" is a value judgement, not a technical limit.
Also, there's no C API for this, so we probably don't need a public C constant for the limit.
There was a problem hiding this comment.
I changed the limit to 32766 characters.
There was a problem hiding this comment.
Also, there's no C API for this, so we probably don't need a public C constant for the limit.
I can rename the macro use _Py prefix. But that unrelated to the Windows implementation, so I would prefer to do it in a separated change. Non-Windows platforms use the same macro.
There was a problem hiding this comment.
Also, there's no C API for this, so we probably don't need a public C constant for the limit.
I created #128945 to make the macro private.
Remove the module methods if GetModuleHandleW() fails.
|
@zooba: Please review the updated PR. I fixed |
|
LGTM |
|
Merged. Thanks for reviews. |
Implement set_name() with SetThreadDescription() and _get_name() with GetThreadDescription(). If SetThreadDescription() or GetThreadDescription() is not available in kernelbase.dll, delete the method when the _thread module is imported. Truncate the thread name to 32766 characters. Co-authored-by: Eryk Sun <eryksun@gmail.com>
Implement set_name() with SetThreadDescription() and _get_name() with GetThreadDescription(). If SetThreadDescription() or GetThreadDescription() is not available in kernelbase.dll, delete the method when the _thread module is imported.
Truncate the thread name to 32766 characters.
set_name() raises ValueError if the name contains an embedded null character.