@@ -76,6 +76,7 @@ get_thread_state_by_cls(PyTypeObject *cls)
7676 return get_thread_state (module );
7777}
7878
79+
7980#ifdef MS_WINDOWS
8081typedef HRESULT (WINAPI * PF_GET_THREAD_DESCRIPTION )(HANDLE , PCWSTR * );
8182typedef HRESULT (WINAPI * PF_SET_THREAD_DESCRIPTION )(HANDLE , PCWSTR );
@@ -2521,11 +2522,38 @@ of the main interpreter.");
25212522# include <pthread_np.h>
25222523#endif
25232524
2524- /* Helper to set the thread name using platform-specific APIs */
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+ */
25252531static int
2526- set_native_thread_name ( const char * name )
2532+ set_encoded_thread_name ( PyObject * name_obj , const char * encoding )
25272533{
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 );
25282555 int rc = 0 ;
2556+
25292557#ifdef __APPLE__
25302558 rc = pthread_setname_np (name );
25312559#elif defined(__NetBSD__ )
@@ -2537,33 +2565,13 @@ set_native_thread_name(const char *name)
25372565#elif defined(HAVE_PTHREAD_SET_NAME_NP )
25382566 pthread_t thread = pthread_self ();
25392567 pthread_set_name_np (thread , name );
2540- rc = 0 ; /* pthread_set_name_np() returns void */
2541- #endif
2542- return rc ;
2543- }
2544-
2545- /* Helper to encode and truncate thread name */
2546- static PyObject *
2547- encode_thread_name (PyObject * name_obj , const char * encoding )
2548- {
2549- PyObject * name_encoded = PyUnicode_AsEncodedString (name_obj , encoding , "replace" );
2550- if (name_encoded == NULL ) {
2551- return NULL ;
2552- }
2553-
2554- #ifdef _PYTHREAD_NAME_MAXLEN
2555- if (PyBytes_GET_SIZE (name_encoded ) > _PYTHREAD_NAME_MAXLEN ) {
2556- PyObject * truncated = PyBytes_FromStringAndSize (PyBytes_AS_STRING (name_encoded ),
2557- _PYTHREAD_NAME_MAXLEN );
2558- Py_DECREF (name_encoded );
2559- if (truncated == NULL ) {
2560- return NULL ;
2561- }
2562- return truncated ;
2563- }
2568+ rc = 0 ; /* that API returns void */
2569+ #else
2570+ rc = 0 ; /* no-op if platform unsupported */
25642571#endif
25652572
2566- return name_encoded ;
2573+ Py_DECREF (name_encoded );
2574+ return rc ;
25672575}
25682576
25692577#if defined(HAVE_PTHREAD_GETNAME_NP ) || defined(HAVE_PTHREAD_GET_NAME_NP ) || defined(MS_WINDOWS )
@@ -2627,48 +2635,51 @@ Set the name of the current thread.
26272635
26282636static PyObject *
26292637_thread_set_name_impl (PyObject * module , PyObject * name_obj )
2630- /*[clinic end generated code: output=402b0c68e0c0daed input=7e7acd98261be82f]*/
26312638{
26322639#ifndef MS_WINDOWS
26332640#ifdef __sun
26342641 // Solaris always uses UTF-8
26352642 const char * encoding = "utf-8" ;
26362643#else
2644+ // Encode the thread name to the filesystem encoding using the "replace"
2645+ // error handler
26372646 PyInterpreterState * interp = _PyInterpreterState_GET ();
26382647 const char * encoding = interp -> unicode .fs_codec .encoding ;
26392648#endif
26402649
2641- /* First attempt using filesystem (or platform) encoding */
2642- PyObject * name_encoded = encode_thread_name (name_obj , encoding );
2643- if (name_encoded == NULL ) {
2650+ int rc = set_encoded_thread_name (name_obj , encoding );
2651+ if (rc == -1 ) {
2652+ /* Confirm a Python exception was set by the helper.
2653+ If not, convert to a runtime error (defensive). */
2654+ if (PyErr_Occurred ()) {
2655+ return NULL ;
2656+ }
2657+ PyErr_SetString (PyExc_RuntimeError , "internal error in set_encoded_thread_name" );
26442658 return NULL ;
26452659 }
2646- const char * name = PyBytes_AS_STRING (name_encoded );
2647- int rc = set_native_thread_name (name );
2648- Py_DECREF (name_encoded );
26492660
2650- /* If native API refused (EINVAL) and we didn't try ASCII, retry with ASCII. */
26512661 if (rc ) {
2662+ /* If native API refused (EINVAL) and we didn't try ASCII, retry with ASCII. */
26522663 if (rc == EINVAL && strcmp (encoding , "ascii" ) != 0 ) {
2653- PyObject * name_encoded2 = encode_thread_name (name_obj , "ascii" );
2654- if (name_encoded2 == NULL ) {
2664+ rc = set_encoded_thread_name (name_obj , "ascii" );
2665+ if (rc == -1 ) {
2666+ if (PyErr_Occurred ()) {
2667+ return NULL ;
2668+ }
2669+ PyErr_SetString (PyExc_RuntimeError , "internal error in set_encoded_thread_name" );
26552670 return NULL ;
26562671 }
2657- const char * name2 = PyBytes_AS_STRING (name_encoded2 );
2658- rc = set_native_thread_name (name2 );
2659- Py_DECREF (name_encoded2 );
2660-
26612672 if (rc == 0 ) {
26622673 Py_RETURN_NONE ;
26632674 }
2664- /* if still failing, fall through to raise errno below */
2675+ /* fall through to raise errno below */
26652676 }
26662677 errno = rc ;
26672678 return PyErr_SetFromErrno (PyExc_OSError );
26682679 }
2669-
26702680 Py_RETURN_NONE ;
26712681#else
2682+ // Windows implementation
26722683 assert (pSetThreadDescription != NULL );
26732684
26742685 Py_ssize_t len ;
@@ -2678,7 +2689,7 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
26782689 }
26792690
26802691 if (len > _PYTHREAD_NAME_MAXLEN ) {
2681- /* Truncate the name */
2692+ // Truncate the name
26822693 Py_UCS4 ch = name [_PYTHREAD_NAME_MAXLEN - 1 ];
26832694 if (Py_UNICODE_IS_HIGH_SURROGATE (ch )) {
26842695 name [_PYTHREAD_NAME_MAXLEN - 1 ] = 0 ;
@@ -2697,7 +2708,6 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
26972708 Py_RETURN_NONE ;
26982709#endif
26992710}
2700-
27012711#endif // HAVE_PTHREAD_SETNAME_NP || HAVE_PTHREAD_SET_NAME_NP || MS_WINDOWS
27022712
27032713
0 commit comments