@@ -47,6 +47,14 @@ get_thread_state(PyObject *module)
47
47
}
48
48
49
49
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
+
50
58
/*[clinic input]
51
59
module _thread
52
60
[clinic start generated code]*/
@@ -2368,7 +2376,7 @@ Internal only. Return a non-zero integer that uniquely identifies the main threa
2368
2376
of the main interpreter." );
2369
2377
2370
2378
2371
- #ifdef HAVE_PTHREAD_GETNAME_NP
2379
+ #if defined( HAVE_PTHREAD_GETNAME_NP ) || defined( MS_WINDOWS )
2372
2380
/*[clinic input]
2373
2381
_thread._get_name
2374
2382
@@ -2379,6 +2387,7 @@ static PyObject *
2379
2387
_thread__get_name_impl (PyObject * module )
2380
2388
/*[clinic end generated code: output=20026e7ee3da3dd7 input=35cec676833d04c8]*/
2381
2389
{
2390
+ #ifndef MS_WINDOWS
2382
2391
// Linux and macOS are limited to respectively 16 and 64 bytes
2383
2392
char name [100 ];
2384
2393
pthread_t thread = pthread_self ();
@@ -2393,11 +2402,26 @@ _thread__get_name_impl(PyObject *module)
2393
2402
#else
2394
2403
return PyUnicode_DecodeFSDefault (name );
2395
2404
#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
2396
2420
}
2397
2421
#endif // HAVE_PTHREAD_GETNAME_NP
2398
2422
2399
2423
2400
- #ifdef HAVE_PTHREAD_SETNAME_NP
2424
+ #if defined( HAVE_PTHREAD_SETNAME_NP ) || defined( MS_WINDOWS )
2401
2425
/*[clinic input]
2402
2426
_thread.set_name
2403
2427
@@ -2410,6 +2434,7 @@ static PyObject *
2410
2434
_thread_set_name_impl (PyObject * module , PyObject * name_obj )
2411
2435
/*[clinic end generated code: output=402b0c68e0c0daed input=7e7acd98261be82f]*/
2412
2436
{
2437
+ #ifndef MS_WINDOWS
2413
2438
#ifdef __sun
2414
2439
// Solaris always uses UTF-8
2415
2440
const char * encoding = "utf-8" ;
@@ -2455,6 +2480,35 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
2455
2480
return PyErr_SetFromErrno (PyExc_OSError );
2456
2481
}
2457
2482
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
2458
2512
}
2459
2513
#endif // HAVE_PTHREAD_SETNAME_NP
2460
2514
@@ -2598,6 +2652,31 @@ thread_module_exec(PyObject *module)
2598
2652
}
2599
2653
#endif
2600
2654
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
+
2601
2680
return 0 ;
2602
2681
}
2603
2682
0 commit comments