On Wednesday, September 10, 2025 8:03:42 PM CEST Daniel P. Berrangé wrote:
> This has greater portability than directly call pthread_setname_np,
> which is only 1 out of 3 possible functions for pthreads that can
> set the name.
> 
> The new API requires a trampoline function, since it can only set
> the name of the current thread.
> 
> Signed-off-by: Daniel P. BerrangĂ© <[email protected]>
> ---
>  audio/jackaudio.c | 30 ++++++++++++++++++++++++------
>  1 file changed, 24 insertions(+), 6 deletions(-)
> 
> diff --git a/audio/jackaudio.c b/audio/jackaudio.c
> index 974a3caad3..69dce3f302 100644
> --- a/audio/jackaudio.c
> +++ b/audio/jackaudio.c
> @@ -629,18 +629,36 @@ static void qjack_enable_in(HWVoiceIn *hw, bool
> enable) ji->c.enabled = enable;
>  }
> 
> -#if !defined(WIN32) && defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
> +#if !defined(WIN32)
> +struct QJackThreadData {
> +    void *(*function)(void *);
> +    void *arg;
> +};
> +
> +static void *qjack_thread_trampoline(void *targ)
> +{
> +    struct QJackThreadData *data = targ;
> +    void *(*function)(void *) = data->function;
> +    void *arg = data->arg;
> +
> +    g_free(data);
> +    qemu_thread_set_name("jack-client");
> +
> +    return function(arg);
> +}
> +
>  static int qjack_thread_creator(jack_native_thread_t *thread,
>      const pthread_attr_t *attr, void *(*function)(void *), void *arg)
>  {
> -    int ret = pthread_create(thread, attr, function, arg);
> +    struct QJackThreadData *data = g_new0(struct QJackThreadData, 1);
> +    data->function = function;
> +    data->arg = arg;
> +    int ret = pthread_create(thread, attr, qjack_thread_trampoline, data);
>      if (ret != 0) {
> +        g_free(data);
>          return ret;
>      }
> 
> -    /* set the name of the thread */
> -    pthread_setname_np(*thread, "jack-client");
> -
>      return ret;
>  }
>  #endif
> @@ -696,7 +714,7 @@ static void register_audio_jack(void)
>  {
>      qemu_mutex_init(&qjack_shutdown_lock);
>      audio_driver_register(&jack_driver);
> -#if !defined(WIN32) && defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
> +#if !defined(WIN32)
>      jack_set_thread_creator(qjack_thread_creator);
>  #endif
>      jack_set_error_function(qjack_error);

Well, it does what you said, so:

Reviewed-by: Christian Schoenebeck <[email protected]>

I just wonder whether this thread naming code couldn't be much more simplified
now by dropping jack_set_thread_creator() entirely, which is very seldomly
used at all and had another user case [1]:

"This function can be used in very very specialized cases where it is
necessary that client threads created by JACK are created by something other
than pthread_create(). After it is used, any threads that JACK needs for the
client will will be created by calling the function passed to this function.

No normal application/client should consider calling this. The specific case
for which it was created involves running win32/x86 plugins under Wine on
Linux, where it is necessary that all threads that might call win32 functions
are known to Wine."

[1] 
https://jackaudio.org/api/group__ClientThreads.html#ga157ab0ade60e266ffd26ddffdb5545af

However there doesn't seem to be a thread creation callback in the JACK API,
so the jack_set_thread_creator() bypass is still the best we can get, right?

/Christian



Reply via email to