1717#ifdef  HAVE_SIGNAL_H 
1818#  include  <signal.h>              // SIGINT 
1919#endif 
20- #ifdef  HAVE_PTHREAD_H 
21- #  include  <pthread.h> 
22- #endif 
23- #include  <errno.h> 
24- #include  <string.h> 
2520
2621// ThreadError is just an alias to PyExc_RuntimeError 
2722#define  ThreadError  PyExc_RuntimeError
@@ -660,13 +655,6 @@ PyThreadHandleObject_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
660655    return  (PyObject  * )PyThreadHandleObject_new (type );
661656}
662657
663- static  int 
664- PyThreadHandleObject_traverse (PyObject  * self , visitproc  visit , void  * arg )
665- {
666-     Py_VISIT (Py_TYPE (self ));
667-     return  0 ;
668- }
669- 
670658static  void 
671659PyThreadHandleObject_dealloc (PyObject  * op )
672660{
@@ -756,7 +744,7 @@ static PyType_Slot ThreadHandle_Type_slots[] = {
756744    {Py_tp_dealloc , PyThreadHandleObject_dealloc },
757745    {Py_tp_repr , PyThreadHandleObject_repr },
758746    {Py_tp_getset , ThreadHandle_getsetlist },
759-     {Py_tp_traverse , PyThreadHandleObject_traverse },
747+     {Py_tp_traverse , _PyObject_VisitType },
760748    {Py_tp_methods , ThreadHandle_methods },
761749    {Py_tp_new , PyThreadHandleObject_tp_new },
762750    {0 , 0 }
@@ -772,13 +760,6 @@ static PyType_Spec ThreadHandle_Type_spec = {
772760
773761/* Lock objects */ 
774762
775- static  int 
776- lock_traverse (PyObject  * self , visitproc  visit , void  * arg )
777- {
778-     Py_VISIT (Py_TYPE (self ));
779-     return  0 ;
780- }
781- 
782763static  void 
783764lock_dealloc (PyObject  * self )
784765{
@@ -1050,7 +1031,7 @@ static PyType_Slot lock_type_slots[] = {
10501031    {Py_tp_repr , lock_repr },
10511032    {Py_tp_doc , (void  * )lock_doc },
10521033    {Py_tp_methods , lock_methods },
1053-     {Py_tp_traverse , lock_traverse },
1034+     {Py_tp_traverse , _PyObject_VisitType },
10541035    {Py_tp_new , lock_new },
10551036    {0 , 0 }
10561037};
@@ -1065,13 +1046,6 @@ static PyType_Spec lock_type_spec = {
10651046
10661047/* Recursive lock objects */ 
10671048
1068- static  int 
1069- rlock_traverse (PyObject  * self , visitproc  visit , void  * arg )
1070- {
1071-     Py_VISIT (Py_TYPE (self ));
1072-     return  0 ;
1073- }
1074- 
10751049static  int 
10761050rlock_locked_impl (rlockobject  * self )
10771051{
@@ -1364,7 +1338,7 @@ static PyType_Slot rlock_type_slots[] = {
13641338    {Py_tp_methods , rlock_methods },
13651339    {Py_tp_alloc , PyType_GenericAlloc },
13661340    {Py_tp_new , rlock_new },
1367-     {Py_tp_traverse , rlock_traverse },
1341+     {Py_tp_traverse , _PyObject_VisitType },
13681342    {0 , 0 },
13691343};
13701344
@@ -2522,58 +2496,6 @@ of the main interpreter.");
25222496#   include  <pthread_np.h> 
25232497#endif 
25242498
2525- /* Helper: encode/truncate and call native API to set thread name. 
2526-  * Return: 
2527-  *   0  : success 
2528-  *   >0 : errno-style native error code (e.g. EINVAL) 
2529-  *  -1  : Python-level error (an exception has been set) 
2530-  */ 
2531- static  int 
2532- set_encoded_thread_name (PyObject  * name_obj , const  char  * encoding )
2533- {
2534-     PyObject  * name_encoded  =  PyUnicode_AsEncodedString (name_obj , encoding , "replace" );
2535-     if  (name_encoded  ==  NULL ) {
2536-         /* PyUnicode_AsEncodedString set an exception */ 
2537-         return  -1 ;
2538-     }
2539- 
2540- #ifdef  _PYTHREAD_NAME_MAXLEN 
2541-     if  (PyBytes_GET_SIZE (name_encoded ) >  _PYTHREAD_NAME_MAXLEN ) {
2542-         PyObject  * truncated  =  PyBytes_FromStringAndSize (
2543-             PyBytes_AS_STRING (name_encoded ),
2544-             _PYTHREAD_NAME_MAXLEN );
2545-         Py_DECREF (name_encoded );
2546-         if  (truncated  ==  NULL ) {
2547-             /* PyBytes_FromStringAndSize set an exception */ 
2548-             return  -1 ;
2549-         }
2550-         name_encoded  =  truncated ;
2551-     }
2552- #endif 
2553- 
2554-     const  char  * name  =  PyBytes_AS_STRING (name_encoded );
2555-     int  rc  =  0 ;
2556- 
2557- #ifdef  __APPLE__ 
2558-     rc  =  pthread_setname_np (name );
2559- #elif  defined(__NetBSD__ )
2560-     pthread_t  thread  =  pthread_self ();
2561-     rc  =  pthread_setname_np (thread , "%s" , (void  * )name );
2562- #elif  defined(HAVE_PTHREAD_SETNAME_NP )
2563-     pthread_t  thread  =  pthread_self ();
2564-     rc  =  pthread_setname_np (thread , name );
2565- #elif  defined(HAVE_PTHREAD_SET_NAME_NP )
2566-     pthread_t  thread  =  pthread_self ();
2567-     pthread_set_name_np (thread , name );
2568-     rc  =  0 ; /* that API returns void */ 
2569- #else 
2570-     rc  =  0 ; /* no-op if platform unsupported */ 
2571- #endif 
2572- 
2573-     Py_DECREF (name_encoded );
2574-     return  rc ;
2575- }
2576- 
25772499#if  defined(HAVE_PTHREAD_GETNAME_NP ) ||  defined(HAVE_PTHREAD_GET_NAME_NP ) ||  defined(MS_WINDOWS )
25782500/*[clinic input] 
25792501_thread._get_name 
@@ -2601,7 +2523,8 @@ _thread__get_name_impl(PyObject *module)
26012523    }
26022524
26032525#ifdef  __sun 
2604-     return  PyUnicode_DecodeUTF8 (name , strlen (name ), "surrogateescape" );
2526+     // Decode Solaris/Illumos (e.g. OpenIndiana) thread names as ASCII with "replace" to avoid decoding errors. 
2527+     return  PyUnicode_DecodeASCII (name , strlen (name ), "replace" );
26052528#else 
26062529    return  PyUnicode_DecodeFSDefault (name );
26072530#endif 
@@ -2639,30 +2562,49 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
26392562{
26402563#ifndef  MS_WINDOWS 
26412564#ifdef  __sun 
2642-     // Solaris always uses UTF-8  
2643-     const  char  * encoding  =  "utf-8 " ;
2565+     // Decode  Solaris/Illumos (e.g. OpenIndiana) thread names as ASCII to avoid decoding errors.  
2566+     const  char  * encoding  =  "ascii " ;
26442567#else 
26452568    // Encode the thread name to the filesystem encoding using the "replace" 
26462569    // error handler 
26472570    PyInterpreterState  * interp  =  _PyInterpreterState_GET ();
26482571    const  char  * encoding  =  interp -> unicode .fs_codec .encoding ;
26492572#endif 
2650- 
2651-     int  rc  =  set_encoded_thread_name (name_obj , encoding );
2652-     /* Confirm a Python exception was set by the helper. 
2653-     If not, convert to a runtime error (defensive). */ 
2654-     if  (rc  ==  -1  &&  PyErr_Occurred ()) {
2573+     PyObject  * name_encoded ;
2574+     name_encoded  =  PyUnicode_AsEncodedString (name_obj , encoding , "replace" );
2575+     if  (name_encoded  ==  NULL ) {
26552576        return  NULL ;
26562577    }
26572578
2658-     /* If native API refused (EINVAL) and we didn't try ASCII, retry with ASCII. */ 
2659-     if  (rc  ==  EINVAL  &&  strcmp (encoding , "ascii" ) !=  0 ) {
2660-         rc  =  set_encoded_thread_name (name_obj , "ascii" );
2661-         if  (rc  ==  -1  &&  PyErr_Occurred ()) {
2579+ #ifdef  _PYTHREAD_NAME_MAXLEN 
2580+     // Truncate to _PYTHREAD_NAME_MAXLEN bytes + the NUL byte if needed 
2581+     if  (PyBytes_GET_SIZE (name_encoded ) >  _PYTHREAD_NAME_MAXLEN ) {
2582+         PyObject  * truncated ;
2583+         truncated  =  PyBytes_FromStringAndSize (PyBytes_AS_STRING (name_encoded ),
2584+                                               _PYTHREAD_NAME_MAXLEN );
2585+         if  (truncated  ==  NULL ) {
2586+             Py_DECREF (name_encoded );
26622587            return  NULL ;
26632588        }
2664-         /* fall through to raise errno below */ 
2589+         Py_SETREF ( name_encoded ,  truncated ); 
26652590    }
2591+ #endif 
2592+ 
2593+     const  char  * name  =  PyBytes_AS_STRING (name_encoded );
2594+ #ifdef  __APPLE__ 
2595+     int  rc  =  pthread_setname_np (name );
2596+ #elif  defined(__NetBSD__ )
2597+     pthread_t  thread  =  pthread_self ();
2598+     int  rc  =  pthread_setname_np (thread , "%s" , (void  * )name );
2599+ #elif  defined(HAVE_PTHREAD_SETNAME_NP )
2600+     pthread_t  thread  =  pthread_self ();
2601+     int  rc  =  pthread_setname_np (thread , name );
2602+ #else  /* defined(HAVE_PTHREAD_SET_NAME_NP) */ 
2603+     pthread_t  thread  =  pthread_self ();
2604+     int  rc  =  0 ; /* pthread_set_name_np() returns void */ 
2605+     pthread_set_name_np (thread , name );
2606+ #endif 
2607+     Py_DECREF (name_encoded );
26662608    if  (rc ) {
26672609        errno  =  rc ;
26682610        return  PyErr_SetFromErrno (PyExc_OSError );
@@ -2932,4 +2874,4 @@ PyMODINIT_FUNC
29322874PyInit__thread (void )
29332875{
29342876    return  PyModuleDef_Init (& thread_module );
2935- }
2877+ }
0 commit comments