@@ -47,6 +47,14 @@ get_thread_state(PyObject *module)
4747}
4848
4949
50+ #ifdef MS_WINDOWS
51+ typedef HRESULT (WINAPI * PF_GET_THREAD_DESCRIPTION )(HANDLE , PCWSTR * );
52+ typedef HRESULT (WINAPI * PF_SET_THREAD_DESCRIPTION )(HANDLE , PCWSTR );
53+ static PF_GET_THREAD_DESCRIPTION pGetThreadDescription = NULL ;
54+ static PF_SET_THREAD_DESCRIPTION pSetThreadDescription = NULL ;
55+ #endif
56+
57+
5058/*[clinic input]
5159module _thread
5260[clinic start generated code]*/
@@ -2368,7 +2376,7 @@ Internal only. Return a non-zero integer that uniquely identifies the main threa
23682376of the main interpreter." );
23692377
23702378
2371- #ifdef HAVE_PTHREAD_GETNAME_NP
2379+ #if defined( HAVE_PTHREAD_GETNAME_NP ) || defined( MS_WINDOWS )
23722380/*[clinic input]
23732381_thread._get_name
23742382
@@ -2379,6 +2387,7 @@ static PyObject *
23792387_thread__get_name_impl (PyObject * module )
23802388/*[clinic end generated code: output=20026e7ee3da3dd7 input=35cec676833d04c8]*/
23812389{
2390+ #ifndef MS_WINDOWS
23822391 // Linux and macOS are limited to respectively 16 and 64 bytes
23832392 char name [100 ];
23842393 pthread_t thread = pthread_self ();
@@ -2393,11 +2402,26 @@ _thread__get_name_impl(PyObject *module)
23932402#else
23942403 return PyUnicode_DecodeFSDefault (name );
23952404#endif
2405+ #else
2406+ // Windows implementation
2407+ assert (pGetThreadDescription != NULL );
2408+
2409+ wchar_t * name ;
2410+ HRESULT hr = pGetThreadDescription (GetCurrentThread (), & name );
2411+ if (FAILED (hr )) {
2412+ PyErr_SetFromWindowsErr (0 );
2413+ return NULL ;
2414+ }
2415+
2416+ PyObject * name_obj = PyUnicode_FromWideChar (name , -1 );
2417+ LocalFree (name );
2418+ return name_obj ;
2419+ #endif
23962420}
23972421#endif // HAVE_PTHREAD_GETNAME_NP
23982422
23992423
2400- #ifdef HAVE_PTHREAD_SETNAME_NP
2424+ #if defined( HAVE_PTHREAD_SETNAME_NP ) || defined( MS_WINDOWS )
24012425/*[clinic input]
24022426_thread.set_name
24032427
@@ -2410,6 +2434,7 @@ static PyObject *
24102434_thread_set_name_impl (PyObject * module , PyObject * name_obj )
24112435/*[clinic end generated code: output=402b0c68e0c0daed input=7e7acd98261be82f]*/
24122436{
2437+ #ifndef MS_WINDOWS
24132438#ifdef __sun
24142439 // Solaris always uses UTF-8
24152440 const char * encoding = "utf-8" ;
@@ -2455,6 +2480,35 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
24552480 return PyErr_SetFromErrno (PyExc_OSError );
24562481 }
24572482 Py_RETURN_NONE ;
2483+ #else
2484+ // Windows implementation
2485+ assert (pSetThreadDescription != NULL );
2486+
2487+ Py_ssize_t len ;
2488+ wchar_t * name = PyUnicode_AsWideCharString (name_obj , & len );
2489+ if (name == NULL ) {
2490+ return NULL ;
2491+ }
2492+
2493+ if (len > PYTHREAD_NAME_MAXLEN ) {
2494+ // Truncate the name
2495+ Py_UCS4 ch = name [PYTHREAD_NAME_MAXLEN - 1 ];
2496+ if (Py_UNICODE_IS_HIGH_SURROGATE (ch )) {
2497+ name [PYTHREAD_NAME_MAXLEN - 1 ] = 0 ;
2498+ }
2499+ else {
2500+ name [PYTHREAD_NAME_MAXLEN ] = 0 ;
2501+ }
2502+ }
2503+
2504+ HRESULT hr = pSetThreadDescription (GetCurrentThread (), name );
2505+ PyMem_Free (name );
2506+ if (FAILED (hr )) {
2507+ PyErr_SetFromWindowsErr ((int )hr );
2508+ return NULL ;
2509+ }
2510+ Py_RETURN_NONE ;
2511+ #endif
24582512}
24592513#endif // HAVE_PTHREAD_SETNAME_NP
24602514
@@ -2598,6 +2652,31 @@ thread_module_exec(PyObject *module)
25982652 }
25992653#endif
26002654
2655+ #ifdef MS_WINDOWS
2656+ HMODULE kernelbase = GetModuleHandleW (L"kernelbase.dll" );
2657+ if (kernelbase != NULL ) {
2658+ if (pGetThreadDescription == NULL ) {
2659+ pGetThreadDescription = (PF_GET_THREAD_DESCRIPTION )GetProcAddress (
2660+ kernelbase , "GetThreadDescription" );
2661+ }
2662+ if (pSetThreadDescription == NULL ) {
2663+ pSetThreadDescription = (PF_SET_THREAD_DESCRIPTION )GetProcAddress (
2664+ kernelbase , "SetThreadDescription" );
2665+ }
2666+ }
2667+
2668+ if (pGetThreadDescription == NULL ) {
2669+ if (PyObject_DelAttrString (module , "_get_name" ) < 0 ) {
2670+ return -1 ;
2671+ }
2672+ }
2673+ if (pSetThreadDescription == NULL ) {
2674+ if (PyObject_DelAttrString (module , "set_name" ) < 0 ) {
2675+ return -1 ;
2676+ }
2677+ }
2678+ #endif
2679+
26012680 return 0 ;
26022681}
26032682
0 commit comments