@@ -75,63 +75,6 @@ get_thread_state_by_cls(PyTypeObject *cls)
7575    return  get_thread_state (module );
7676}
7777
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- 
13578#ifdef  MS_WINDOWS 
13679typedef  HRESULT  (WINAPI  * PF_GET_THREAD_DESCRIPTION )(HANDLE , PCWSTR * );
13780typedef  HRESULT  (WINAPI  * PF_SET_THREAD_DESCRIPTION )(HANDLE , PCWSTR );
@@ -2636,38 +2579,110 @@ _thread.set_name
26362579Set the name of the current thread. 
26372580[clinic start generated code]*/ 
26382581
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 */ 
26392633static  PyObject  * 
26402634_thread_set_name_impl (PyObject  * module , PyObject  * name_obj )
26412635/*[clinic end generated code: output=402b0c68e0c0daed input=7e7acd98261be82f]*/ 
26422636{
26432637#ifndef  MS_WINDOWS 
2638+ #ifdef  __sun 
2639+     const  char  * encoding  =  "utf-8" ;
2640+ #else 
26442641    PyInterpreterState  * interp  =  _PyInterpreterState_GET ();
26452642    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. */ 
26472655    if  (rc ) {
26482656        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 ;
26532660            }
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 */ 
26552669        }
26562670        errno  =  rc ;
26572671        return  PyErr_SetFromErrno (PyExc_OSError );
26582672    }
2673+ 
26592674    Py_RETURN_NONE ;
26602675#else 
2661-     // Windows implementation 
26622676    assert (pSetThreadDescription  !=  NULL );
2663-      
2677+ 
26642678    Py_ssize_t  len ;
26652679    wchar_t  * name  =  PyUnicode_AsWideCharString (name_obj , & len );
26662680    if  (name  ==  NULL ) {
26672681        return  NULL ;
26682682    }
2683+ 
26692684    if  (len  >  _PYTHREAD_NAME_MAXLEN ) {
2670-         //  Truncate the name 
2685+         /*  Truncate the name */  
26712686        Py_UCS4  ch  =  name [_PYTHREAD_NAME_MAXLEN - 1 ];
26722687        if  (Py_UNICODE_IS_HIGH_SURROGATE (ch )) {
26732688            name [_PYTHREAD_NAME_MAXLEN - 1 ] =  0 ;
@@ -2676,6 +2691,7 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
26762691            name [_PYTHREAD_NAME_MAXLEN ] =  0 ;
26772692        }
26782693    }
2694+ 
26792695    HRESULT  hr  =  pSetThreadDescription (GetCurrentThread (), name );
26802696    PyMem_Free (name );
26812697    if  (FAILED (hr )) {
@@ -2685,6 +2701,7 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
26852701    Py_RETURN_NONE ;
26862702#endif 
26872703}
2704+ 
26882705#endif   // HAVE_PTHREAD_SETNAME_NP || HAVE_PTHREAD_SET_NAME_NP || MS_WINDOWS 
26892706
26902707
0 commit comments