@@ -75,63 +75,6 @@ get_thread_state_by_cls(PyTypeObject *cls)
75
75
return get_thread_state (module );
76
76
}
77
77
78
- // Helper to set the thread name using platform-specific APIs
79
- static int
80
- set_native_thread_name (const char * name )
81
- {
82
- int rc ;
83
- #ifdef __APPLE__
84
- rc = pthread_setname_np (name );
85
- #elif defined(__NetBSD__ )
86
- pthread_t thread = pthread_self ();
87
- rc = pthread_setname_np (thread , "%s" , (void * )name );
88
- #elif defined(HAVE_PTHREAD_SETNAME_NP )
89
- pthread_t thread = pthread_self ();
90
- rc = pthread_setname_np (thread , name );
91
- #elif defined(HAVE_PTHREAD_SET_NAME_NP )
92
- pthread_t thread = pthread_self ();
93
- pthread_set_name_np (thread , name );
94
- rc = 0 ; /* pthread_set_name_np() returns void */
95
- #endif
96
- return rc ;
97
- }
98
-
99
- // Helper to encode and truncate thread name
100
- static PyObject *
101
- encode_thread_name (PyObject * name_obj , const char * encoding )
102
- {
103
- #ifdef __sun
104
- // Solaris always uses UTF-8
105
- encoding = "utf-8" ;
106
- #endif
107
- PyObject * name_encoded = PyUnicode_AsEncodedString (name_obj , encoding , "replace" );
108
- if (name_encoded == NULL ) {
109
- return NULL ;
110
- }
111
- #ifdef _PYTHREAD_NAME_MAXLEN
112
- if (PyBytes_GET_SIZE (name_encoded ) > _PYTHREAD_NAME_MAXLEN ) {
113
- PyObject * truncated = PyBytes_FromStringAndSize (PyBytes_AS_STRING (name_encoded ), _PYTHREAD_NAME_MAXLEN );
114
- Py_DECREF (name_encoded );
115
- return truncated ;
116
- }
117
- #endif
118
- return name_encoded ;
119
- }
120
-
121
- // Helper to encode, set, and cleanup thread name in one step
122
- static int
123
- set_thread_name_with_encoding (PyObject * name_obj , const char * encoding )
124
- {
125
- PyObject * name_encoded = encode_thread_name (name_obj , encoding );
126
- if (name_encoded == NULL ) {
127
- return -1 ; // error, exception set
128
- }
129
- const char * name = PyBytes_AS_STRING (name_encoded );
130
- int rc = set_native_thread_name (name );
131
- Py_DECREF (name_encoded );
132
- return rc ;
133
- }
134
-
135
78
#ifdef MS_WINDOWS
136
79
typedef HRESULT (WINAPI * PF_GET_THREAD_DESCRIPTION )(HANDLE , PCWSTR * );
137
80
typedef HRESULT (WINAPI * PF_SET_THREAD_DESCRIPTION )(HANDLE , PCWSTR );
@@ -2636,38 +2579,110 @@ _thread.set_name
2636
2579
Set the name of the current thread.
2637
2580
[clinic start generated code]*/
2638
2581
2582
+ /* Helper to set the thread name using platform-specific APIs */
2583
+ static int
2584
+ set_native_thread_name (const char * name )
2585
+ {
2586
+ int rc = 0 ;
2587
+ #ifdef __APPLE__
2588
+ rc = pthread_setname_np (name );
2589
+ #elif defined(__NetBSD__ )
2590
+ pthread_t thread = pthread_self ();
2591
+ rc = pthread_setname_np (thread , "%s" , (void * )name );
2592
+ #elif defined(HAVE_PTHREAD_SETNAME_NP )
2593
+ pthread_t thread = pthread_self ();
2594
+ rc = pthread_setname_np (thread , name );
2595
+ #elif defined(HAVE_PTHREAD_SET_NAME_NP )
2596
+ pthread_t thread = pthread_self ();
2597
+ pthread_set_name_np (thread , name );
2598
+ rc = 0 ; /* pthread_set_name_np() returns void */
2599
+ #endif
2600
+ return rc ;
2601
+ }
2602
+
2603
+ /* Helper to encode and truncate thread name; returns new reference or NULL */
2604
+ static PyObject *
2605
+ encode_thread_name (PyObject * name_obj , const char * encoding )
2606
+ {
2607
+ #ifdef __sun
2608
+ /* Solaris always uses UTF-8 */
2609
+ encoding = "utf-8" ;
2610
+ #endif
2611
+
2612
+ PyObject * name_encoded = PyUnicode_AsEncodedString (name_obj , encoding , "replace" );
2613
+ if (name_encoded == NULL ) {
2614
+ return NULL ;
2615
+ }
2616
+
2617
+ #ifdef _PYTHREAD_NAME_MAXLEN
2618
+ if (PyBytes_GET_SIZE (name_encoded ) > _PYTHREAD_NAME_MAXLEN ) {
2619
+ PyObject * truncated = PyBytes_FromStringAndSize (PyBytes_AS_STRING (name_encoded ),
2620
+ _PYTHREAD_NAME_MAXLEN );
2621
+ Py_DECREF (name_encoded );
2622
+ if (truncated == NULL ) {
2623
+ return NULL ;
2624
+ }
2625
+ return truncated ;
2626
+ }
2627
+ #endif
2628
+
2629
+ return name_encoded ;
2630
+ }
2631
+
2632
+ /* Implementation of _thread.set_name */
2639
2633
static PyObject *
2640
2634
_thread_set_name_impl (PyObject * module , PyObject * name_obj )
2641
2635
/*[clinic end generated code: output=402b0c68e0c0daed input=7e7acd98261be82f]*/
2642
2636
{
2643
2637
#ifndef MS_WINDOWS
2638
+ #ifdef __sun
2639
+ const char * encoding = "utf-8" ;
2640
+ #else
2644
2641
PyInterpreterState * interp = _PyInterpreterState_GET ();
2645
2642
const char * encoding = interp -> unicode .fs_codec .encoding ;
2646
- int rc = set_thread_name_with_encoding (name_obj , encoding );
2643
+ #endif
2644
+
2645
+ /* First attempt using filesystem (or platform) encoding */
2646
+ PyObject * name_encoded = encode_thread_name (name_obj , encoding );
2647
+ if (name_encoded == NULL ) {
2648
+ return NULL ;
2649
+ }
2650
+ const char * name = PyBytes_AS_STRING (name_encoded );
2651
+ int rc = set_native_thread_name (name );
2652
+ Py_DECREF (name_encoded );
2653
+
2654
+ /* If native API refused (EINVAL) and we didn't try ASCII, retry with ASCII. */
2647
2655
if (rc ) {
2648
2656
if (rc == EINVAL && strcmp (encoding , "ascii" ) != 0 ) {
2649
- rc = set_thread_name_with_encoding (name_obj , "ascii" );
2650
- if (rc ) {
2651
- errno = rc ;
2652
- return PyErr_SetFromErrno (PyExc_OSError );
2657
+ PyObject * name_encoded2 = encode_thread_name (name_obj , "ascii" );
2658
+ if (name_encoded2 == NULL ) {
2659
+ return NULL ;
2653
2660
}
2654
- Py_RETURN_NONE ;
2661
+ const char * name2 = PyBytes_AS_STRING (name_encoded2 );
2662
+ rc = set_native_thread_name (name2 );
2663
+ Py_DECREF (name_encoded2 );
2664
+
2665
+ if (rc == 0 ) {
2666
+ Py_RETURN_NONE ;
2667
+ }
2668
+ /* if still failing, fall through to raise errno below */
2655
2669
}
2656
2670
errno = rc ;
2657
2671
return PyErr_SetFromErrno (PyExc_OSError );
2658
2672
}
2673
+
2659
2674
Py_RETURN_NONE ;
2660
2675
#else
2661
- // Windows implementation
2662
2676
assert (pSetThreadDescription != NULL );
2663
-
2677
+
2664
2678
Py_ssize_t len ;
2665
2679
wchar_t * name = PyUnicode_AsWideCharString (name_obj , & len );
2666
2680
if (name == NULL ) {
2667
2681
return NULL ;
2668
2682
}
2683
+
2669
2684
if (len > _PYTHREAD_NAME_MAXLEN ) {
2670
- // Truncate the name
2685
+ /* Truncate the name */
2671
2686
Py_UCS4 ch = name [_PYTHREAD_NAME_MAXLEN - 1 ];
2672
2687
if (Py_UNICODE_IS_HIGH_SURROGATE (ch )) {
2673
2688
name [_PYTHREAD_NAME_MAXLEN - 1 ] = 0 ;
@@ -2676,6 +2691,7 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
2676
2691
name [_PYTHREAD_NAME_MAXLEN ] = 0 ;
2677
2692
}
2678
2693
}
2694
+
2679
2695
HRESULT hr = pSetThreadDescription (GetCurrentThread (), name );
2680
2696
PyMem_Free (name );
2681
2697
if (FAILED (hr )) {
@@ -2685,6 +2701,7 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
2685
2701
Py_RETURN_NONE ;
2686
2702
#endif
2687
2703
}
2704
+
2688
2705
#endif // HAVE_PTHREAD_SETNAME_NP || HAVE_PTHREAD_SET_NAME_NP || MS_WINDOWS
2689
2706
2690
2707
0 commit comments